jQuery `.is („: widoczny ”)` nie działa w 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>

Powyższy kod działa płynnie w przeglądarce Firefox, ale wydaje się, że nie działa w przeglądarce Chrome. W Chrome pokazuje to .is(":visible") = falsenawet wtedy, gdy jest true.

Korzystam z następującej wersji jQuery: jquery-1.4.3.min.js

jsFiddle Link: http://jsfiddle.net/WJU2r/4/

Saad Bashir
źródło
1
najlepiej w link jsfiddle? i ewentualnie sprawdź to za pomocą jquery.latest.
xaxxon,
makaspan może być wyświetlany: brak lub widoczność: ukryty?
Artur Keyan,
a może tymczasowo zaktualizować do najnowszej wersji jQuery, aby wykluczyć błąd jQuery?
Strelok
1
Zobacz także: bugs.jquery.com/ticket/13132 Wygląda na to, że zostanie to naprawione w wersji 1.12 / 2.2! -
Glen Little
1
nie trzeba dodawać „== true” w piśmie if: if ($ („# makespan”). is is („: visible”)) is enougth
marcdahan

Odpowiedzi:

273

Wygląda na to, że :visibleselektor jQuery nie działa w przypadku niektórych elementów wbudowanych w Chrome. Rozwiązaniem jest dodanie stylu wyświetlania, takiego jak "block"lub uruchomienie "inline-block"go.

Zauważ też, że jQuery ma nieco inną definicję tego, co jest widoczne niż wielu programistów:

Elementy są uważane za widoczne, jeśli zajmują miejsce w dokumencie.
Widoczne elementy mają szerokość lub wysokość większą niż zero.

Innymi słowy, element musi mieć niezerową szerokość i wysokość, aby zajmować miejsce i być widoczny.

Elementy z visibility: hiddenlub opacity: 0są uważane za widoczne, ponieważ nadal zajmują miejsce w układzie.

Z drugiej strony, nawet jeśli visibilityjest ustawiony na hiddenlub nieprzezroczystość wynosi zero, to nadal :visiblezajmuje jQuery, ponieważ zajmuje miejsce, co może być mylące, gdy CSS wyraźnie mówi, że jego widoczność jest ukryta.

Elementy, których nie ma w dokumencie, są uważane za ukryte; jQuery nie ma sposobu, aby wiedzieć, czy będą widoczne po dołączeniu do dokumentu, ponieważ zależy to od odpowiednich stylów.

Wszystkie elementy opcji są uważane za ukryte, niezależnie od ich wybranego stanu.

Podczas animacji, które ukrywają element, element jest uważany za widoczny do końca animacji. Podczas animacji pokazujących element element uważa się za widoczny na początku animacji.

Prostym sposobem na to jest to, że jeśli widzisz element na ekranie, nawet jeśli nie widzisz jego zawartości, jest przezroczysty itp., Jest widoczny, tj. Zajmuje miejsce.

Wyczyściłem trochę twój znacznik i dodałem styl wyświetlania ( tj. Ustawianie wyświetlania elementów na „blok” itp. ), A to działa dla mnie:

SKRZYPCE

Oficjalne odniesienie API dla :visible


Od jQuery 3 definicja :visiblenieznacznie się zmieniła

jQuery 3 nieznacznie modyfikuje znaczenie :visible(a zatem i :hidden).
Począwszy od tej wersji, elementy będą brane pod uwagę, :visiblejeśli mają jakieś pola układu, w tym te o zerowej szerokości i / lub wysokości. Na przykład selektor brwybierze elementy i elementy wbudowane bez zawartości :visible.

adeneo
źródło
Próbowałem też wkleić poszczególne komponenty w jsFiddle i działało dobrze. Spróbuję powtórzyć błąd w jsFiddle, a następnie opublikować link. Prawdopodobnie coś innego w kodzie powoduje ten błąd
Saad Bashir
Replikowałem problem pod następującym linkiem: jsfiddle.net/WJU2r/3
Saad Bashir
3
Dzięki bardzo, że działało! Nie wiem dlaczego, ale ustawiam #makespan {display: block; } sprawiło, że działało.
Saad Bashir
Komentarz z oryginalnego plakatu zawiera rzeczywiste rozwiązanie IE, dzięki czemu zakresy display: block. Głupie, że rozpiętości są domyślnie niewidoczne w chromie, ale cokolwiek.
Jeff Davis,
Wystarczy dodać & nbsp; do elementu, ponieważ jeśli element nie ma treści, jest niewidoczny w Chrome
Briganti
67

Nie wiem, dlaczego twój kod nie działa na Chrome, ale sugeruję, abyś zastosował kilka obejść:

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

lub

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

Jeśli masz pewność, że jQuery daje złe wyniki w chrome, możesz po prostu polegać na sprawdzeniu reguły css:

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

Ponadto możesz użyć najnowszej wersji jQuery, ponieważ może ona zawierać błędy ze starszej wersji.

gion_13
źródło
2
Skopiowałem
Saad Bashir
To pytanie szczegółowo określa różnicę między :hiddeni :not(:visible). stackoverflow.com/questions/17425543/…
Mark Schultheiss
funkcja jest („: widoczny”) lub .is („: ukryty”) lub jest („: nie (: ukryty)”) bardzo źle działa
Diogo Cid,
9

Istnieje dziwny przypadek, w którym jeśli element jest ustawiony display: inlinena jQuery, sprawdzanie widoczności kończy się niepowodzeniem.

Przykład:

CSS

#myspan {display: inline;}

jQuery

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

Aby to naprawić, możesz ukryć element w jQuery i wtedy show/hidelub toggle()powinien działać dobrze.

$('#myspan').hide()
$('#otherElement').on('click', function() {
    $('#myspan').toggle();
});
Alex Rashkov
źródło
Mam ten problem z PhantomJS, ale w Chrome 47.0.2526 wydaje się, że to działa. patrz: jsfiddle.net/k4b925gn/2
ekkis
8

Zakładam, że ma to coś wspólnego z dziwactwem w naszym HTML, ponieważ inne miejsca na tej samej stronie działają dobrze.

Jedynym sposobem, w jaki udało mi się rozwiązać ten problem, było:

if($('#element_id').css('display') == 'none')
{
   // Take element is hidden action
}
else
{
   // Take element is visible action
}
Chris Dutrow
źródło
7

Jeśli czytasz dokumenty jquery, istnieje wiele powodów, dla których nie można uznać, że są widoczne / ukryte:

Mają wartość wyświetlania CSS równą none.

Są to elementy form o typie = „ukryty”.

Ich szerokość i wysokość są jawnie ustawione na 0.

Element nadrzędny jest ukryty, więc element nie jest wyświetlany na stronie.

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

Oto mały przykład jsfiddle z jednym widocznym i jednym ukrytym elementem:

http://jsfiddle.net/tNjLb/

xaxxon
źródło
Skopiowałem problem pod następującym linkiem: jsfiddle.net/WJU2r/3
Saad Bashir
7

Internet Explorer, Chrome, Firefox ...

Funkcja Cross Browser „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;
    }
}

Pełny przykład:

<!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>

Pozdrowienia,

Fernando

Fernando
źródło
3

Zasadniczo żyję w tej sytuacji, gdy rodzic mojego obiektu jest ukryty. na przykład, gdy HTML jest taki:

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

jeśli zapytasz, czy dziecko jest widoczne, takie jak:

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

zwróci false, ponieważ jego rodzic nie jest widoczny, więc div również nie będzie widoczny.

cenk ebret
źródło
zobacz moje rozwiązanie niżej ... w twoim dziecku ustaw wyświetlanie na „dziedziczenie”, które skopiuje stan z jego elementu nadrzędnego, więc jeśli to jest ukryte, elemtn.is („: hidden”) zadziała
Patrick
3

Rozwiązaniem między przeglądarkami / wersjami, aby ustalić, czy element jest widoczny, jest dodanie / usunięcie klasy css do elementu podczas show / hide. Domyślny (widoczny) stan elementu może wyglądać następująco:

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

Następnie ukryj, usuń klasę:

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

Przy pokazie dodaj go ponownie:

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

Następnie, aby ustalić, czy element jest widoczny, użyj tego:

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

To rozwiązuje również wpływ na wydajność, który może wystąpić przy intensywnym używaniu selektora „: visible”, które są wskazane w dokumentacji jQuery:

Silne użycie tego selektora może mieć wpływ na wydajność, ponieważ może zmusić przeglądarkę do ponownego renderowania strony, zanim będzie mogła określić widoczność. Śledzenie widoczności elementów innymi metodami, na przykład za pomocą klasy, może zapewnić lepszą wydajność.

Oficjalna dokumentacja API jQuery dla selektora „: visible”

Alex
źródło
1

Dodałem następny styl nadrzędny i .is („: visible”) działało.

display: blok wbudowany;

Horatiu
źródło
0

Jeśli element potomny elementu, który jest ukryty, to („: visible”) zwróci true, co jest niepoprawne.

Właśnie to naprawiłem, dodając element „display: dziedziczenie” do elementu potomnego. To naprawi to dla mnie:

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

i CSS:

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

Teraz element można skutecznie włączać i wyłączać, zmieniając widoczność elementu nadrzędnego, a $ (element) .is („: visible”) zwróci widoczność elementu nadrzędnego

Patrick
źródło
0

To jest fragment kodu z jquery.js, który jest wykonywany, gdy nazywa się („: 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 );
    };
}

Jak widać, wykorzystuje więcej niż tylko właściwość wyświetlania CSS. Zależy to również od szerokości i wysokości zawartości elementu. Dlatego upewnij się, że element ma pewną szerokość i wysokość. Aby to zrobić, konieczne może być ustawienie właściwości display na "inline-block"lub "block"

hkulur
źródło
0

Muszę użyć widoczności: ukryta instancja wyświetlania: brak, ponieważ widoczność wymaga zdarzeń, a wyświetlanie nie.

Ja również .attr('visibility') === "visible"

mitjajez
źródło