jQuery `.is («: visible »)` не работает в Chrome

207
if ($("#makespan").is(":visible") == true) { 
    var make = $("#make").val(); 
}
else {
    var make = $("#othermake").val(); 
}

Make:<span id=makespan><select id=make></select><span id=othermakebutton class=txtbutton>Other?</span></span><span id=othermakespan style="display: none;"><input type=text name=othermake id=othermake>&nbsp;-&nbsp;<span id=othermakecancel class=txtbutton>Cancel</span></span>

Приведенный выше код работает в Firefox без сбоев, но, похоже, не работает в Chrome. В Chrome это показывает .is(":visible") = falseдаже когда оно есть true.

Я использую следующую версию jQuery: jquery-1.4.3.min.js

Ссылка jsFiddle: http://jsfiddle.net/WJU2r/4/

Саад Башир
источник
1
желательно в ссылке jsfiddle? и, возможно, проверить это с помощью jquery.latest.
xaxxon
Макаспан может отображаться: нет или видимость: скрыто?
Артур Кейан
и, возможно, временно обновиться до последней версии jQuery, чтобы исключить ошибку jQuery?
Стрелок
1
Смотрите также: bugs.jquery.com/ticket/13132 Похоже, это будет исправлено в версии 1.12 / 2.2! -
Глен Литтл
1
не нужно добавлять «== true» в операторе if: if ($ ("makepan"). is (": visible")) достаточно
marcdahan

Ответы:

273

Кажется, :visibleселектор jQuery не работает для некоторых встроенных элементов в Chrome. Решение состоит в том, чтобы добавить стиль отображения, как "block"или "inline-block"заставить его работать.

Также обратите внимание, что jQuery имеет несколько иное определение того, что видно, чем многие разработчики:

Элементы считаются видимыми, если они занимают место в документе.
Видимые элементы имеют ширину или высоту больше нуля.

Другими словами, элемент должен иметь ненулевую ширину и высоту, чтобы занимать пространство и быть видимым.

Элементы с visibility: hiddenили opacity: 0считаются видимыми, поскольку они все еще занимают место в макете.

С другой стороны, даже если для него visibilityустановлено значение hiddenили непрозрачность равна нулю, он все равно работает :visibleс jQuery, поскольку он занимает место, что может сбивать с толку, когда CSS явно говорит, что его видимость скрыта.

Элементы, которых нет в документе, считаются скрытыми; У jQuery нет способа узнать, будут ли они видны при добавлении в документ, поскольку это зависит от применяемых стилей.

Все элементы опции считаются скрытыми, независимо от их выбранного состояния.

Во время анимации, которая скрывает элемент, элемент считается видимым до конца анимации. Во время анимации, чтобы показать элемент, элемент считается видимым в начале анимации.

Самый простой способ посмотреть на это, это то, что если вы видите элемент на экране, даже если вы не видите его содержимое, он прозрачный и т. Д., Он видим, то есть занимает место.

Я немного очистил вашу разметку и добавил стиль отображения ( т.е. установил отображение элементов на «block» и т. Д. ), И это работает для меня:

FIDDLE

Официальная ссылка на API для :visible


Начиная с jQuery 3, определение :visible немного изменилось

jQuery 3 слегка изменяет значение :visible(и, следовательно, :hidden).
Начиная с этой версии, элементы будут рассматриваться, :visibleесли у них есть какие-либо поля макета, в том числе с нулевой шириной и / или высотой. Например, селектор brбудет выбирать элементы и встроенные элементы без содержимого :visible.

adeneo
источник
Я также попытался вставить отдельные компоненты в jsFiddle, и он работал нормально. Я постараюсь повторить ошибку в jsFiddle, а затем опубликовать ссылку. Возможно, что-то еще в коде вызывает эту ошибку
Саад Башир
Я повторил проблему по следующей ссылке: jsfiddle.net/WJU2r/3
Саад Башир
3
Большое спасибо, что работал! Я не знаю почему, но установка #makespan {display: block; } заставил это работать.
Саад Башир
Комментарий от оригинального постера содержит фактическое решение, IE, заставляющее ваши промежутки отображать: блок. Глупо, что пролеты невидимы по умолчанию в chrome, но, что угодно.
Джефф Дэвис
Это достаточно, если вы добавите & nbsp; к элементу, потому что, если элемент не имеет содержимого, то он невидим в Chrome
Briganti
67

Я не знаю, почему ваш код не работает на Chrome, но я предлагаю вам использовать некоторые обходные пути:

$el.is(':visible') === $el.is(':not(:hidden)');

или

$el.is(':visible') === !$el.is(':hidden');  

Если вы уверены, что JQuery дает вам некоторые плохие результаты в Chrome, вы можете просто положиться на проверку правила CSS:

if($el.css('display') !== 'none') {
    // i'm visible
}

Кроме того, вы можете использовать последнюю версию jQuery, потому что в ней могут быть исправлены ошибки более старой версии.

gion_13
источник
2
Я повторил проблему по следующей ссылке: jsfiddle.net/WJU2r/3
Саад Башир
Этот вопрос подробно описывает разницу между :hiddenи :not(:visible). stackoverflow.com/questions/17425543/…
Марк
функция (': visible') или .is (': hidden') или is (': not (: hidden)') очень плохо работает
Diogo Cid
9

Существует странный случай, когда элемент установлен в display: inline в jQuery, проверка на видимость завершается неудачей.

Пример:

CSS

#myspan {display: inline;}

JQuery

$('#myspan').show(); // Our element is `inline` instead of `block`
$('#myspan').is(":visible"); // This is false

Чтобы это исправить, можно скрыть элемент в JQuery и чем show/hideили toggle()должны работать нормально.

$('#myspan').hide()
$('#otherElement').on('click', function() {
    $('#myspan').toggle();
});
Алекс Рашков
источник
У меня эта проблема с PhantomJS, но на Chrome 47.0.2526 это, кажется, работает. см .: jsfiddle.net/k4b925gn/2
ekkis
8

Я предполагаю, что это как-то связано с причудой в нашем HTML, потому что другие места на той же странице работают просто отлично.

Единственный способ решить эту проблему - это сделать:

if($('#element_id').css('display') == 'none')
{
   // Take element is hidden action
}
else
{
   // Take element is visible action
}
Крис Датроу
источник
7

Если вы читаете документы jquery, существует множество причин, по которым что-то нельзя считать видимым / скрытым:

У них есть CSS значение отображения ни одного.

Это элементы формы с type = "hidden".

Их ширина и высота явно установлены на 0.

Элемент-предок скрыт, поэтому элемент не отображается на странице.

http://api.jquery.com/visible-selector/

Вот небольшой пример jsfiddle с одним видимым и одним скрытым элементом:

http://jsfiddle.net/tNjLb/

xaxxon
источник
Я повторил проблему по следующей ссылке: jsfiddle.net/WJU2r/3
Саад Башир
7

Internet Explorer, Chrome, Firefox ...

Кросс-браузерная функция "isVisible ()"

//check if exist and is visible
function isVisible(id) {
    var element = $('#' + id);
    if (element.length > 0 && element.css('visibility') !== 'hidden' && element.css('display') !== 'none') {
        return true;
    } else {
        return false;
    }
}

Полный пример:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
        <script type="text/javascript">
            //check if exist and is visible
            function isVisible(id) {
                var element = $('#' + id);
                if (element.length > 0 && element.css('visibility') !== 'hidden' && element.css('display') !== 'none') {
                    return true;
                } else {
                    return false;
                }
            }

            function check(id) {
                if (isVisible(id)) {
                    alert('visible: true');
                } else {
                    alert('visible: false');
                }
                return false;
            }
        </script>

        <style type="text/css">
            #fullname{
                display: none;
            }
            #vote{
                visibility: hidden;
            }
        </style>
        <title>Full example: isVisible function</title>
    </head>
    <body>
        <div id="hello-world">
            Hello World!
        </div>
        <div id="fullname">
            Fernando Mosquera Catarecha
        </div>
        <div id="vote">
            rate it!
        </div>
        <a href="#" onclick="check('hello-world');">Check isVisible('hello-world')</a><br /><br />
        <a href="#" onclick="check('fullname');">Check isVisible('fullname')</a><br /><br />
        <a href="#" onclick="check('vote');">Check isVisible('vote')</a>
    </body>
</html>

С Уважением,

Фернандо

Фернандо
источник
3

Обычно я живу в такой ситуации, когда родитель моего объекта скрыт. например, когда HTML-код выглядит так:

    <div class="div-parent" style="display:none">
        <div class="div-child" style="display:block">
        </div>
    </div>

если вы спросите, виден ли ребенок как:

    $(".div-child").is(":visible");

он вернет false, потому что его родитель не виден, так что div также не будет виден.

Ченк Эбрет
источник
посмотрите мое решение ниже ... в вашем дочернем наборе установите значение «наследовать», которое будет копировать состояние из его родительского элемента, поэтому, если это скрыто, сработает elemtn.is (": hidden")
Патрик
3

Решение кросс-браузер / версия, чтобы определить, является ли элемент видимым, состоит в добавлении / удалении класса css к элементу на show / hide. Состояние элемента по умолчанию (видимое) может быть, например, таким:

<span id="span1" class="visible">Span text</span>

Затем при скрытии удалите класс:

$("#span1").removeClass("visible").hide();

На шоу, добавьте это снова:

$("#span1").addClass("visible").show();

Затем, чтобы определить, является ли элемент видимым, используйте это:

if ($("#span1").hasClass("visible")) { // do something }

Это также решает проблемы с производительностью, которые могут возникнуть при интенсивном использовании селектора «: visible», которые указаны в документации jQuery:

Сильное использование этого селектора может повлиять на производительность, так как может заставить браузер повторно визуализировать страницу, прежде чем он сможет определить видимость. Отслеживание видимости элементов с помощью других методов, например, с использованием класса, может обеспечить более высокую производительность.

Официальная документация по jQuery API для селектора ": visible"

Alex
источник
1

Я добавил следующий стиль для родителя, и .is (": visible") сработал.

дисплей: встроенный блок;

Horatiu
источник
0

Если элемент является потомком скрытого элемента (": visible"), он вернет true, что неверно.

Я просто исправил это, добавив «display: наследовать» к дочернему элементу. Это будет исправлено для меня:

<div class="parent">
   <div class="child">
   </div>
<div>

и CSS:

.parent{
   display: hidden;
}
.child{
   display: inherit;
}

Теперь элемент можно эффективно включать и выключать, изменяя видимость родительского элемента, а $ (element) .is (": visible") будет возвращать видимость родительского элемента.

Патрик
источник
0

Это фрагмент кода из jquery.js, который выполняется, когда вызывается (": visible"):

if (jQuery.expr && jQuery.expr.filters){

    jQuery.expr.filters.hidden = function( elem ) {
        return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
    };

    jQuery.expr.filters.visible = function( elem ) {
        return !jQuery.expr.filters.hidden( elem );
    };
}

Как видите, он использует больше, чем просто свойство отображения CSS. Это также зависит от ширины и высоты содержимого элемента. Следовательно, убедитесь, что элемент имеет некоторую ширину и высоту. И для этого вам может потребоваться установить для свойства display значение "inline-block"или "block"

hkulur
источник
0

Мне нужно использовать видимость: скрытая установка отображения: нет, потому что видимость принимает события, а отображение - нет.

Так и делаю .attr('visibility') === "visible"

mitjajez
источник