jQuery `.ist (": sichtbar ")` funktioniert in Chrome nicht

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>

Der obige Code läuft in Firefox reibungslos, scheint jedoch in Chrome nicht zu funktionieren. In Chrome wird es .is(":visible") = falseauch dann angezeigt, wenn es ist true.

Ich verwende die folgende jQuery-Version: jquery-1.4.3.min.js

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

Saad Bashir
quelle
1
vorzugsweise in einem jsfiddle link? und überprüfen Sie es möglicherweise mit jquery.latest.
Xaxxon
Der Makaspan kann angezeigt werden: keine oder Sichtbarkeit: versteckt?
Artur Keyan
und vielleicht vorübergehend auf die neueste jQuery-Version aktualisieren, um einen jQuery-Fehler auszuschließen?
Strelok
1
Siehe auch: bugs.jquery.com/ticket/13132 Scheint, als würde es in Version 1.12 / 2.2 behoben! -
Glen Little
1
Sie müssen nicht "== true" in die if-Anweisung einfügen: if ($ ("# makespan"). is (": visible")) ist enougth
marcdahan

Antworten:

273

Es scheint, dass die Auswahl von jQuery :visiblefür einige Inline-Elemente in Chrome nicht funktioniert. Die Lösung besteht darin, einen Anzeigestil hinzuzufügen, der "block"oder "inline-block"funktioniert.

Beachten Sie auch, dass jQuery eine etwas andere Definition dessen hat, was sichtbar ist als viele Entwickler:

Elemente gelten als sichtbar, wenn sie Speicherplatz im Dokument belegen.
Sichtbare Elemente haben eine Breite oder Höhe, die größer als Null ist.

Mit anderen Worten, ein Element muss eine Breite und Höhe ungleich Null haben, um Platz zu beanspruchen und sichtbar zu sein.

Elemente mit visibility: hiddenoder opacity: 0werden als sichtbar betrachtet, da sie noch Platz im Layout beanspruchen.

Auf der anderen Seite visibilityist jQuery hiddenimmer noch :visiblefür jQuery, da es Speicherplatz verbraucht , selbst wenn es auf Null gesetzt ist oder die Deckkraft Null ist. Dies kann verwirrend sein, wenn das CSS ausdrücklich angibt, dass seine Sichtbarkeit verborgen ist.

Elemente, die sich nicht in einem Dokument befinden, werden als ausgeblendet betrachtet. jQuery kann nicht feststellen, ob sie beim Anhängen an ein Dokument sichtbar sind, da dies von den jeweiligen Stilen abhängt.

Alle Optionselemente werden unabhängig von ihrem ausgewählten Status als ausgeblendet betrachtet.

Bei Animationen, bei denen ein Element ausgeblendet wird, wird das Element bis zum Ende der Animation als sichtbar betrachtet. Während Animationen ein Element anzeigen, wird das Element zu Beginn der Animation als sichtbar betrachtet.

Die einfache Möglichkeit, es zu betrachten, besteht darin, dass wenn Sie das Element auf dem Bildschirm sehen können, auch wenn Sie seinen Inhalt nicht sehen können, es transparent usw. ist, es sichtbar ist, dh Platz beansprucht.

Ich habe Ihr Markup ein wenig aufgeräumt und einen Anzeigestil hinzugefügt ( dh die Elementanzeige auf "Blockieren" usw. setzen ), und das funktioniert für mich:

GEIGE

Offizielle API-Referenz für :visible


Ab jQuery 3 hat sich die Definition von :visibleleicht geändert

jQuery 3 ändert die Bedeutung von :visible(und daher von :hidden) geringfügig .
Ab dieser Version werden Elemente berücksichtigt, :visiblewenn sie Layoutfelder haben, einschließlich solcher mit einer Breite und / oder Höhe von Null. Beispielsweise werden brElemente und Inline-Elemente ohne Inhalt von der Auswahl ausgewählt :visible.

Adeneo
quelle
Ich habe auch versucht, die einzelnen Komponenten in jsFiddle einzufügen, und es hat gut funktioniert. Ich werde versuchen, den Fehler in jsFiddle zu replizieren und dann den Link zu posten. Wahrscheinlich verursacht etwas anderes im Code diesen Fehler
Saad Bashir
Ich habe das Problem auf dem folgenden Link repliziert: jsfiddle.net/WJU2r/3
Saad Bashir
3
Vielen Dank, dass es funktioniert hat! Ich weiß nicht warum, aber setze #makespan {display: block; } hat es funktioniert.
Saad Bashir
Der Kommentar aus dem Originalposter enthält die eigentliche Lösung, IE, sodass Ihre Bereiche angezeigt werden: Block. Dumm, dass Spannweiten in Chrom standardmäßig unsichtbar sind, aber was auch immer.
Jeff Davis
Es ist ausreichend, wenn Sie eine & nbsp; zum Element, denn wenn ein Element keinen Inhalt hat, ist es in Chrome
Briganti
67

Ich weiß nicht, warum Ihr Code auf Chrome nicht funktioniert, aber ich schlage vor, dass Sie einige Problemumgehungen verwenden:

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

oder

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

Wenn Sie sicher sind, dass jQuery in Chrome zu schlechten Ergebnissen führt, können Sie sich einfach auf die Überprüfung der CSS-Regeln verlassen:

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

Außerdem möchten Sie möglicherweise die neueste jQuery verwenden, da möglicherweise Fehler aus einer älteren Version behoben wurden.

gion_13
quelle
2
Ich habe das Problem auf dem folgenden Link repliziert: jsfiddle.net/WJU2r/3
Saad Bashir
Diese Frage beschreibt den Unterschied zwischen :hiddenund :not(:visible). stackoverflow.com/questions/17425543/…
Mark Schultheiss
Die Funktion ist (': sichtbar') oder .is (': versteckt') oder ist (': nicht (: versteckt)') sehr schlecht für die Leistung
Diogo Cid
9

Es gibt einen seltsamen Fall, in dem display: inlinedie Prüfung auf Sichtbarkeit fehlschlägt, wenn das Element auf jQuery gesetzt ist .

Beispiel:

CSS

#myspan {display: inline;}

jQuery

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

Um dies zu beheben, können Sie das Element in jQuery ausblenden und dann show/hideoder toggle()sollte es gut funktionieren.

$('#myspan').hide()
$('#otherElement').on('click', function() {
    $('#myspan').toggle();
});
Alex Rashkov
quelle
Ich habe dieses Problem mit PhantomJS, aber unter Chrome 47.0.2526 scheint dies zu funktionieren. siehe: jsfiddle.net/k4b925gn/2
ekkis
8

Ich gehe davon aus, dass es etwas mit einer Eigenart in unserem HTML zu tun hat, da andere Stellen auf derselben Seite einwandfrei funktionieren.

Ich konnte dieses Problem nur lösen, indem ich Folgendes tat:

if($('#element_id').css('display') == 'none')
{
   // Take element is hidden action
}
else
{
   // Take element is visible action
}
Chris Dutrow
quelle
7

Wenn Sie die JQuery-Dokumente lesen, gibt es zahlreiche Gründe dafür, dass etwas nicht als sichtbar / verborgen betrachtet wird:

Sie haben einen CSS-Anzeigewert von none.

Sie sind Formularelemente mit type = "hidden".

Ihre Breite und Höhe werden explizit auf 0 gesetzt.

Ein Vorfahrenelement ist ausgeblendet, sodass das Element nicht auf der Seite angezeigt wird.

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

Hier ist ein kleines jsfiddle-Beispiel mit einem sichtbaren und einem versteckten Element:

http://jsfiddle.net/tNjLb/

xaxxon
quelle
Ich habe das Problem auf dem folgenden Link repliziert: jsfiddle.net/WJU2r/3
Saad Bashir
7

Internet Explorer, Chrome, Firefox ...

Browserübergreifende Funktion "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;
    }
}

Vollständiges Beispiel:

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

Grüße,

Fernando

Fernando
quelle
3

Im Allgemeinen lebe ich diese Situation, wenn Eltern meines Objekts versteckt sind. Zum Beispiel, wenn das HTML so ist:

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

wenn Sie fragen, ob das Kind sichtbar ist wie:

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

Es wird false zurückgegeben, da das übergeordnete Element nicht sichtbar ist, sodass div auch nicht sichtbar ist.

Cenk Ebret
quelle
siehe meine Lösung unten ... in der Anzeige Ihres untergeordneten Satzes auf "erben", wodurch der Status von seinem übergeordneten Element kopiert wird. Wenn dies also versteckt ist, funktioniert elemtn.is (": hidden")
Patrick
3

Eine browser- / versionübergreifende Lösung, um festzustellen, ob ein Element sichtbar ist, besteht darin, dem Element beim Ein- / Ausblenden eine CSS-Klasse hinzuzufügen / zu entfernen. Der Standardzustand (sichtbar) des Elements könnte beispielsweise folgendermaßen aussehen:

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

Entfernen Sie dann beim Ausblenden die Klasse:

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

Fügen Sie es erneut hinzu:

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

Verwenden Sie dann Folgendes, um festzustellen, ob das Element sichtbar ist:

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

Dies löst auch die Auswirkungen auf die Leistung, die bei starker Verwendung des Selektors ": sichtbar" auftreten können und auf die in der Dokumentation von jQuery verwiesen wird:

Die häufige Verwendung dieses Selektors kann Auswirkungen auf die Leistung haben, da der Browser die Seite möglicherweise erneut rendern muss, bevor die Sichtbarkeit bestimmt werden kann. Das Verfolgen der Sichtbarkeit von Elementen mithilfe anderer Methoden, z. B. mithilfe einer Klasse, kann zu einer besseren Leistung führen.

Offizielle jQuery-API-Dokumentation für den Selektor ": sichtbar"

Alex
quelle
1

Ich habe den nächsten Stil für das übergeordnete Element hinzugefügt und .is (": sichtbar") hat funktioniert.

Anzeige: Inline-Block;

Horatiu
quelle
0

Wenn ein Element einem untergeordneten Element untergeordnet ist, wird (": sichtbar") true zurückgegeben, was falsch ist.

Ich habe dies gerade behoben, indem ich dem untergeordneten Element "display: inherit" hinzugefügt habe. Dies wird es für mich behoben:

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

und das CSS:

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

Jetzt kann das Element durch Ändern der Sichtbarkeit des übergeordneten Elements effektiv ein- und ausgeschaltet werden, und $ (element) .is (": sichtbar") gibt die Sichtbarkeit des übergeordneten Elements zurück

Patrick
quelle
0

Dies ist der Code aus jquery.js, der ausgeführt wird, wenn is (": sichtbar") aufgerufen wird:

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 );
    };
}

Wie Sie sehen, wird mehr als nur die CSS-Anzeigeeigenschaft verwendet. Dies hängt auch von der Breite und Höhe des Inhalts des Elements ab. Stellen Sie daher sicher, dass das Element eine gewisse Breite und Höhe hat. Dazu müssen Sie möglicherweise die Anzeigeeigenschaft auf "inline-block"oder setzen "block"

hkulur
quelle
0

Ich muss Sichtbarkeit verwenden: versteckte Anzeige: keine, da Sichtbarkeit Ereignisse akzeptiert , während die Anzeige dies nicht tut.

So ich mache .attr('visibility') === "visible"

Mitjajez
quelle