jQuery `.is (": visible ")` non funziona in Chrome


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

Il codice sopra funziona senza problemi in Firefox, ma non sembra funzionare in Chrome. In Chrome mostra .is(":visible") = falseanche quando lo è true.

Sto usando la seguente versione di jQuery: jquery-1.4.3.min.js

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


1
preferibilmente in un collegamento jsfiddle? e possibilmente controllarlo con jquery.latest.
xaxxon

il makaspan può essere visualizzato: nessuno o visibilità: nascosto?
Artur Keyan

e magari aggiornare temporaneamente l'ultima versione di jQuery, solo per escludere un bug di jQuery?
Strelok

1
Vedi anche: bugs.jquery.com/ticket/13132 Sembra che verrà corretto nella versione 1.12 / 2.2! -
Glen Little

2
non è necessario aggiungere "== true" nell'istruzione if scrivendo: if ($ ("# makespan"). is (": visible")) è sufficiente
marcdahan

Risposte:


275

Sembra che il :visibleselettore di jQuery non funzioni per alcuni elementi inline in Chrome. La soluzione è aggiungere uno stile di visualizzazione, come "block"o "inline-block"per farlo funzionare.

Si noti inoltre che jQuery ha una definizione leggermente diversa di ciò che è visibile rispetto a molti sviluppatori:

Gli elementi sono considerati visibili se occupano spazio nel documento.
Gli elementi visibili hanno una larghezza o un'altezza maggiore di zero.

In altre parole, un elemento deve avere larghezza e altezza diverse da zero per consumare spazio ed essere visibile.

Gli elementi con visibility: hiddeno opacity: 0sono considerati visibili, poiché occupano ancora spazio nel layout.

D'altra parte, anche se visibilityè impostato su hiddeno l'opacità è zero, è ancora :visiblesu jQuery poiché consuma spazio, il che può creare confusione quando il CSS dice esplicitamente che la sua visibilità è nascosta.

Gli elementi che non sono in un documento sono considerati nascosti; jQuery non ha un modo per sapere se saranno visibili quando vengono aggiunti a un documento poiché dipende dagli stili applicabili.

Tutti gli elementi delle opzioni sono considerati nascosti, indipendentemente dal loro stato selezionato.

Durante le animazioni che nascondono un elemento, l'elemento è considerato visibile fino alla fine dell'animazione. Durante le animazioni per mostrare un elemento, l'elemento è considerato visibile all'inizio dell'animazione.

Il modo più semplice per vederlo è che se puoi vedere l'elemento sullo schermo, anche se non puoi vedere il suo contenuto, è trasparente ecc., È visibile, cioè occupa spazio.

Ho ripulito un po 'il tuo markup e aggiunto uno stile di visualizzazione (ad esempio, impostando la visualizzazione degli elementi su "block" ecc. ), E questo funziona per me:

VIOLINO

Riferimento API ufficiale per :visible


A partire da jQuery 3, la definizione di :visibleè leggermente cambiata

jQuery 3 modifica leggermente il significato di :visible(e quindi di :hidden).
A partire da questa versione, verranno presi in considerazione gli elementi :visiblese hanno delle caselle di layout, comprese quelle di larghezza e / o altezza zero. Ad esempio, gli brelementi e gli elementi in linea senza contenuto verranno selezionati dal :visibleselettore.


Ho anche provato a incollare i singoli componenti in jsFiddle e ha funzionato bene. Proverò a replicare l'errore in jsFiddle e quindi pubblicare il collegamento. Probabilmente qualcos'altro nel codice sta causando questo errore
Saad Bashir

Ho replicato il problema al seguente link: jsfiddle.net/WJU2r/3
Saad Bashir

3
Grazie mille che ha funzionato! Non so perché ma impostando #makespan {display: block; } l'ha fatto funzionare.
Saad Bashir

Il commento dal poster originale contiene la soluzione effettiva, IE, che mostra gli intervalli: blocco. Sciocco che le campate sono invisibili per impostazione predefinita in Chrome, ma, qualunque cosa.
Jeff Davis

È sufficiente se aggiungi un & nbsp; all'elemento, perché se un elemento non ha contenuto allora è invisibile in Chrome
Briganti

70

Non so perché il tuo codice non funziona su Chrome, ma ti suggerisco di utilizzare alcune soluzioni alternative:

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

o

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

Se sei certo che jQuery ti dia dei cattivi risultati in chrome, puoi semplicemente fare affidamento sul controllo delle regole CSS:

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

Inoltre, potresti voler utilizzare l' ultima jQuery perché potrebbe avere bug della versione precedente corretti.


2
Ho replicato il problema al seguente link: jsfiddle.net/WJU2r/3
Saad Bashir

Questa domanda descrive in dettaglio qual è la differenza tra :hiddene :not(:visible). stackoverflow.com/questions/17425543/…
Mark Schultheiss

la funzione è (': visible') o .is (': hidden') o is (': not (: hidden)') è pessima per le prestazioni
Diogo Cid

9

Presumo che abbia qualcosa a che fare con una stranezza nel nostro HTML perché altri posti sulla stessa pagina funzionano bene.

L'unico modo in cui sono stato in grado di risolvere questo problema era di fare:

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

9

C'è un caso strano in cui se l'elemento è impostato su display: inlinejQuery, il controllo della visibilità fallisce.

Esempio:

CSS

#myspan {display: inline;}

jQuery

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

Per risolverlo puoi nascondere l'elemento in jQuery e quindi show/hideo toggle()dovrebbe funzionare bene.

$('#myspan').hide()
$('#otherElement').on('click', function() {
    $('#myspan').toggle();
});

Ho questo problema con PhantomJS ma su Chrome 47.0.2526 sembra funzionare. vedi: jsfiddle.net/k4b925gn/2
ekkis

8

Internet Explorer, Chrome, Firefox ...

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

Esempio completo:

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

Saluti,

Fernando


7

Se leggi i documenti jquery, ci sono numerosi motivi per cui qualcosa non può essere considerato visibile / nascosto:

Hanno un valore di visualizzazione CSS pari a nessuno.

Sono elementi del modulo con type = "hidden".

La loro larghezza e altezza sono impostate esplicitamente su 0.

Un elemento antenato è nascosto, quindi l'elemento non viene mostrato nella pagina.

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

Ecco un piccolo esempio di jsfiddle con un elemento visibile e uno nascosto:

http://jsfiddle.net/tNjLb/


Ho replicato il problema al seguente link: jsfiddle.net/WJU2r/3
Saad Bashir

3

Generalmente vivo questa situazione quando il genitore del mio oggetto è nascosto. per esempio quando l'html è così:

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

se chiedi se il bambino è visibile come:

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

restituirà false perché il suo genitore non è visibile, quindi anche div non sarà visibile.


vedi la mia soluzione più in basso ... nel tuo bambino imposta display su 'inherit', questo copierà lo stato dal suo elemento genitore, quindi se è nascosto elemtn.is (": hidden") funzionerà
patrick

3

Una soluzione cross browser / versione per determinare se un elemento è visibile, consiste nell'aggiungere / rimuovere una classe CSS all'elemento in mostra / nascondi. Lo stato predefinito (visibile) dell'elemento potrebbe essere, ad esempio, questo:

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

Quindi su nascondi, rimuovi la classe:

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

In mostra, aggiungilo di nuovo:

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

Quindi per determinare se l'elemento è visibile, usa questo:

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

Questo risolve anche le implicazioni sulle prestazioni, che possono verificarsi con un uso intenso del selettore ": visible", che sono indicate nella documentazione di jQuery:

L'utilizzo pesante di questo selettore può avere implicazioni sulle prestazioni, poiché potrebbe costringere il browser a rieseguire il rendering della pagina prima che possa determinare la visibilità. Il monitoraggio della visibilità degli elementi tramite altri metodi, ad esempio utilizzando una classe, può fornire prestazioni migliori.

Documentazione ufficiale dell'API jQuery per il selettore ": visible"


1

Ho aggiunto lo stile successivo al genitore e .is (": visible") ha funzionato.

display: blocco in linea;


0

Se un elemento è figlio di un elemento nascosto, è (": visibile") restituirà vero, che non è corretto.

Ho appena risolto questo problema aggiungendo "display: inherit" all'elemento figlio. Questo lo risolverà per me:

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

e il CSS:

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

Ora l'elemento può essere efficacemente attivato e disattivato modificando la visibilità dell'elemento padre e $ (element) .is (": visible") restituirà la visibilità dell'elemento padre


0

Questo è il pezzo di codice da jquery.js che viene eseguito quando viene chiamato is (": 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 );
    };
}

Come puoi vedere, utilizza più della semplice proprietà di visualizzazione CSS. Dipende anche dalla larghezza e dall'altezza del contenuto dell'elemento. Quindi, assicurati che l'elemento abbia una certa larghezza e altezza. E per fare ciò, potrebbe essere necessario impostare la proprietà display su "inline-block"o "block"


0

Ho bisogno di usare la visibilità: nascosto invece di display: nessuno perché la visibilità prende gli eventi, mentre il display no.

Faccio così .attr('visibility') === "visible"

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.