jQuery `.is(":visible")` 在 Chrome 中不起作用

Posted

技术标签:

【中文标题】jQuery `.is(":visible")` 在 Chrome 中不起作用【英文标题】:jQuery `.is(":visible")` not working in Chrome 【发布时间】:2012-01-10 08:27:36 【问题描述】:
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/

【问题讨论】:

最好在 jsfiddle 链接中?并可能使用 jquery.latest 进行检查。 makaspan 可能是 display: none 或 visibility: hidden? 并且可能会暂时更新到最新的 jQuery 版本,只是为了排除 jQuery 错误? 另见:bugs.jquery.com/ticket/13132 似乎它将在版本 1.12/2.2 中修复! —— 不需要在 if 语句中添加“ == true ” : if ($("#makespan").is(":visible") ) 足够 【参考方案1】:

似乎 jQuery 的 :visible 选择器不适用于 Chrome 中的某些内联元素。解决方案是添加一个显示样式,如"block""inline-block" 以使其工作。

另外请注意,与许多开发人员相比,jQuery 对可见内容的定义有些不同:

如果元素占用了文档中的空间,则认为它们是可见的。 可见元素的宽度或高度大于零。

换句话说,一个元素必须具有非零的宽度和高度才能占用空间并可见。

带有visibility: hiddenopacity: 0 的元素被认为是可见的, 因为它们仍然会占用布局中的空间。

另一方面,即使它的 visibility 设置为 hidden 或不透明度为零,它仍然是 jQuery 的 :visible,因为它会占用空间,当 CSS 明确表示它的可见性是隐藏。

不在文档中的元素被认为是隐藏的; jQuery 确实 无法知道它们在附加到时是否可见 文档,因为它取决于适用的样式。

所有选项元素都被认为是隐藏的,无论它们的 选中状态。

在隐藏元素的动画期间,该元素被认为是 直到动画结束可见。在动画期间显示 元素,该元素在开始时被认为是可见的 动画。

看它的简单方法是,如果你能在屏幕上看到元素,即使你看不到它的内容,它是透明的等等,它是可见的,即它占用空间。

我稍微清理了您的标记并添加了一种显示样式(即将元素显示设置为“块”等),这对我有用:

FIDDLE

Official API reference for :visible


从 jQuery 3 开始,:visible 的定义略有变化

jQuery 3 稍微修改了:visible 的含义(因此 :hidden)。 从这个版本开始,将考虑元素 :visible 如果他们有任何布局框,包括那些零宽度的 和/或高度。例如,br 元素和内联元素没有 内容将由:visible 选择器选择。

【讨论】:

我还尝试将各个组件粘贴到 jsFiddle 中,效果很好。我将尝试在 jsFiddle 中复制错误,然后发布链接。可能代码中的其他内容导致此错误 我已经在以下链接上复制了这个问题:jsfiddle.net/WJU2r/3 非常感谢您的工作!我不知道为什么,但设置 #makespan display: block; 让它工作。 来自原始海报的评论包含实际的解决方案,IE,使您的跨度显示:块。愚蠢的跨度默认情况下在 chrome 中是不可见的,但是,无论如何。 加个   就够了到元素,因为如果一个元素没有内容,那么它在 Chrome 中是不可见的【参考方案2】:

我不知道为什么你的代码不能在 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

另外,您可能想要使用latest jQuery,因为它可能修复了旧版本的错误。

【讨论】:

我在以下链接上复制了这个问题:jsfiddle.net/WJU2r/3 这个问题详细说明了:hidden:not(:visible) 之间的区别。 ***.com/questions/17425543/… 函数is(':visible') or .is(':hidden') or is(':not(:hidden)') 对性能非常不利【参考方案3】:

我认为这与我们 html 中的一个怪癖有关,因为同一页面上的其他地方工作正常。

我能够解决这个问题的唯一方法是:

if($('#element_id').css('display') == 'none')

   // Take element is hidden action

else

   // Take element is visible action

【讨论】:

【参考方案4】:

有一个奇怪的情况,如果元素设置为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/hidetoggle() 应该可以正常工作。

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

【讨论】:

我在使用 PhantomJS 时遇到了这个问题,但在 Chrome 47.0.2526 上这似乎有效。见:jsfiddle.net/k4b925gn/2【参考方案5】:

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>

问候,

费尔南多

【讨论】:

【参考方案6】:

如果您阅读 jquery 文档,有很多原因导致某些内容不被视为可见/隐藏:

它们的 CSS 显示值为 none。

它们是 type="hidden" 的表单元素。

它们的宽度和高度被明确设置为 0。

祖先元素被隐藏,因此该元素不会显示在页面上。

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

这是一个带有一个可见元素和一个隐藏元素的小型 jsfiddle 示例:

http://jsfiddle.net/tNjLb/

【讨论】:

我已经在以下链接上复制了这个问题:jsfiddle.net/WJU2r/3【参考方案7】:

确定元素是否可见的跨浏览器/版本解决方案是在显示/隐藏时向元素添加/删除 css 类。元素的默认(可见)状态可能是这样的:

&lt;span id="span1" class="visible"&gt;Span text&lt;/span&gt;

然后隐藏,删除类:

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

在节目中,再次添加:

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

然后判断元素是否可见,使用这个:

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

这也解决了性能问题,这可能在大量使用 jQuery 文档中指出的 ":visible" 选择器时发生:

大量使用此选择器可能会影响性能,因为它可能会强制浏览器在确定可见性之前重新渲染页面。通过其他方法(例如使用类)跟踪元素的可见性可以提供更好的性能。

Official jQuery API Documentation for ":visible" selector

【讨论】:

【参考方案8】:

通常,当我的对象的父对象隐藏时,我会遇到这种情况。 例如当 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") 将工作【参考方案9】:

我在父级上添加了下一个样式,并且 .is(":visible") 起作用了。

显示:内联块;

【讨论】:

【参考方案10】:

我需要使用 visibility:hidden insted of display:none 因为 visibility 需要事件,而 display没有。

所以我做.attr('visibility') === "visible"

【讨论】:

【参考方案11】:

如果某项是隐藏项的子项,则 is(":visible") 将返回 true,这是不正确的。

我刚刚通过将“display:inherit”添加到子项来解决此问题。这将为我修复它:

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

和 CSS:

.parent
   display: hidden;

.child
   display: inherit;

现在可以通过改变父项的可见性来有效地打开和关闭项,$(element).is(":visible") 将返回父项的可见性

【讨论】:

【参考方案12】:

这是 jquery.js 中的一段代码,它在 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 );
    ;

如您所见,它使用的不仅仅是 CSS 显示属性。它还取决于元素内容的宽度和高度。因此,请确保元素具有一定的宽度和高度。为此,您可能需要将 display 属性设置为 "inline-block""block"

【讨论】:

以上是关于jQuery `.is(":visible")` 在 Chrome 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

jQuery已切换项

如何检查元素是不是隐藏在 jQuery 中?

如何检查元素是不是隐藏在 jQuery 中?

如何检查元素是不是隐藏在 jQuery 中?

如何监听dom元素的显示隐藏事件

使用 jQuery 选择样式为“visibility:visible”或“visibility:hidden”而不是“display:none”的项目