jQuery `.is (“: visible ”)` no funciona en 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>

El código anterior se ejecuta sin problemas en Firefox, pero no parece funcionar en Chrome. En Chrome se muestra .is(":visible") = falseincluso cuando es así true.

Estoy usando la siguiente versión de jQuery: jquery-1.4.3.min.js

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

Saad Bashir
fuente
1
preferiblemente en un enlace jsfiddle? y posiblemente verifíquelo con jquery.latest.
xaxxon
el makaspan puede mostrarse: ninguno, o visibilidad: oculta?
Artur Keyan
y quizás actualizar a la última versión de jQuery temporalmente, solo para descartar un error de jQuery?
Strelok
1
Consulte también: bugs.jquery.com/ticket/13132 ¡ Parece que se solucionará en la versión 1.12 / 2.2! -
Glen Little
1
no es necesario agregar "== verdadero" en la escritura de la declaración if: if ($ ("# makespan"). is (": visible")) es suficiente
marcdahan

Respuestas:

273

Parece que el :visibleselector de jQuery no funciona para algunos elementos en línea en Chrome. La solución es agregar un estilo de visualización, como "block"o "inline-block"para que funcione.

También tenga en cuenta que jQuery tiene una definición algo diferente de lo que es visible que muchos desarrolladores:

Los elementos se consideran visibles si consumen espacio en el documento.
Los elementos visibles tienen un ancho o alto mayor que cero.

En otras palabras, un elemento debe tener un ancho y una altura distintos de cero para consumir espacio y ser visibles.

Elementos con visibility: hiddeno opacity: 0se consideran visibles, ya que aún consumen espacio en el diseño.

Por otro lado, incluso si visibilityse establece en hiddeno la opacidad es cero, todavía :visiblees jQuery ya que consume espacio, lo que puede ser confuso cuando el CSS dice explícitamente que su visibilidad está oculta.

Los elementos que no están en un documento se consideran ocultos; jQuery no tiene una manera de saber si serán visibles cuando se agreguen a un documento, ya que depende de los estilos aplicables.

Todos los elementos de opción se consideran ocultos, independientemente de su estado seleccionado.

Durante las animaciones que ocultan un elemento, el elemento se considera visible hasta el final de la animación. Durante las animaciones para mostrar un elemento, el elemento se considera visible al comienzo de la animación.

La manera fácil de verlo es que si puede ver el elemento en la pantalla, incluso si no puede ver su contenido, es transparente, etc., es visible, es decir, ocupa espacio.

Limpié un poco su marcado y agregué un estilo de visualización ( es decir, configurar la visualización de elementos para "bloquear", etc. ), y esto funciona para mí:

VIOLÍN

Referencia oficial de API para :visible


A partir de jQuery 3, la definición de :visibleha cambiado ligeramente

jQuery 3 modifica ligeramente el significado de :visible(y por lo tanto de :hidden).
A partir de esta versión, se considerarán los elementos :visiblesi tienen cuadros de diseño, incluidos los de ancho y / o alto cero. Por ejemplo, brel :visibleselector seleccionará elementos y elementos en línea sin contenido .

adeneo
fuente
También intenté pegar los componentes individuales en jsFiddle y funcionó bien. Intentaré replicar el error en jsFiddle y luego publicar el enlace. Probablemente algo más en el código está causando este error
Saad Bashir
He replicado el problema en el siguiente enlace: jsfiddle.net/WJU2r/3
Saad Bashir
3
Muchas gracias que funcionó! No sé por qué, pero configurando #makespan {display: block; } lo hizo funcionar.
Saad Bashir
El comentario del póster original contiene la solución real, IE, haciendo que se muestre su espacio: bloque. Tonto que abarca son invisibles por defecto en cromo, pero, lo que sea.
Jeff Davis
Es suficiente si agrega un & nbsp; para el elemento, porque si un elemento no tiene contenido, entonces es invisible en Chrome
Briganti
67

No sé por qué su código no funciona en Chrome, pero le sugiero que use algunas soluciones:

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

o

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

Si está seguro de que jQuery le da algunos malos resultados en Chrome, puede confiar en la comprobación de reglas CSS:

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

Además, es posible que desee utilizar la última versión de jQuery porque puede haber corregido errores de versiones anteriores.

gion_13
fuente
2
He replicado el problema en el siguiente enlace: jsfiddle.net/WJU2r/3
Saad Bashir
Esta pregunta detalla cuál es la diferencia entre :hiddeny :not(:visible). stackoverflow.com/questions/17425543/…
Mark Schultheiss el
la función es (': visible') o .is (': hidden') o is (': not (: hidden)') es muy mala para el rendimiento
Diogo Cid
9

Hay un caso extraño en el que si el elemento se establece en display: inlinejQuery, la comprobación de visibilidad falla.

Ejemplo:

CSS

#myspan {display: inline;}

jQuery

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

Para solucionarlo, puede ocultar el elemento en jQuery y entonces show/hideo toggle()debería funcionar bien.

$('#myspan').hide()
$('#otherElement').on('click', function() {
    $('#myspan').toggle();
});
Alex Rashkov
fuente
Tengo este problema con PhantomJS pero en Chrome 47.0.2526 parece funcionar. ver: jsfiddle.net/k4b925gn/2
ekkis
8

Supongo que tiene algo que ver con una peculiaridad en nuestro HTML porque otros lugares en la misma página funcionan bien.

La única forma en que pude resolver este problema fue hacer:

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

Si lee los documentos de jquery, existen numerosas razones para que algo no se considere visible / oculto:

Tienen un valor de visualización CSS de ninguno.

Son elementos de formulario con type = "hidden".

Su ancho y alto se establecen explícitamente en 0.

Un elemento ancestro está oculto, por lo que el elemento no se muestra en la página.

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

Aquí hay un pequeño ejemplo de jsfiddle con un elemento visible y otro oculto:

http://jsfiddle.net/tNjLb/

xaxxon
fuente
He replicado el problema en el siguiente enlace: jsfiddle.net/WJU2r/3
Saad Bashir
7

Internet Explorer, Chrome, Firefox ...

Función de navegador cruzado "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;
    }
}

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

Saludos,

Fernando

Fernando
fuente
3

En general, vivo esta situación cuando el padre de mi objeto está oculto. por ejemplo cuando el html es así:

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

si pregunta si el niño es visible como:

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

devolverá falso porque su padre no es visible, por lo que div no será visible también.

cenk ebret
fuente
vea mi solución más abajo ... en su pantalla de configuración secundaria para 'heredar', eso copiará el estado de su elemento principal, por lo que si está oculto elemtn.is (": hidden") funcionará
patrick
3

Una solución de navegador cruzado / versión para determinar si un elemento es visible, es agregar / eliminar una clase css al elemento en show / hide. El estado predeterminado (visible) del elemento podría ser, por ejemplo, así:

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

Luego, en hide, elimina la clase:

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

En el programa, agréguelo nuevamente:

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

Luego, para determinar si el elemento es visible, use esto:

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

Esto también resuelve las implicaciones de rendimiento, que pueden ocurrir en el uso intensivo del selector ": visible", que se señalan en la documentación de jQuery:

El uso intensivo de este selector puede tener implicaciones de rendimiento, ya que puede obligar al navegador a volver a representar la página antes de que pueda determinar la visibilidad. El seguimiento de la visibilidad de los elementos a través de otros métodos, utilizando una clase, por ejemplo, puede proporcionar un mejor rendimiento.

Documentación oficial de la API jQuery para el selector ": visible"

Alex
fuente
1

Agregué el siguiente estilo en el padre y .is (": visible") funcionó.

pantalla: bloque en línea;

Horatiu
fuente
0

Si un elemento es hijo de un elemento que está oculto, es (": visible") devolverá verdadero, lo cual es incorrecto.

Acabo de arreglar esto agregando "display: heredar" al elemento secundario. Esto lo arreglará para mí:

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

y el CSS:

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

Ahora el elemento se puede activar y desactivar de manera efectiva cambiando la visibilidad del elemento primario, y $ (element) .is (": visible") devolverá la visibilidad del elemento primario

Patricio
fuente
0

Este es el fragmento de código de jquery.js que se ejecuta cuando is (": visible") se llama:

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

Como puede ver, utiliza más que solo la propiedad de visualización CSS. También depende del ancho y alto del contenido del elemento. Por lo tanto, asegúrese de que el elemento tenga algo de ancho y alto. Y para hacer esto, es posible que deba establecer la propiedad de visualización en "inline-block"o "block"

hkulur
fuente
0

Necesito usar visibilidad: oculto en la pantalla: ninguno porque la visibilidad toma eventos, mientras que la pantalla no.

Así que hago .attr('visibility') === "visible"

mitjajez
fuente