隐藏选择器总是决定元素是否可见,即使它不是

时间:2013-08-07 16:10:12

标签: javascript jquery hidden false-positive

我正在为即将开展的项目工作的一件事是标注/工具提示系统。从理论上讲,这是一个简单的小事。你需要一些标记,如this

<script src='jQuery 1.10.1'></script>
<a href='#' id='callout-link'>Click Me</a>

<div id='callout-id' class='callout hidden'>
    This is my tooltip text.
</div>

/* CSS Styling... */
.callout {
     position: absolute;
     z-index: 2;
}

.hidden {
     display: none;
}

...并在JavaScript中将其绑定,以便每当您点击某个链接时,它都会切换可见性。

// ...Page Script...
var $link = $('#callout-link'),
    $callout = $('#callout-id');

$(document).ready(function () {
    var callout = new MyCallout($link, $callout);
    callout.bindToControlClick();
});

// ...Object Definition...
var MyCallout = function ($control, $callout) {
    init();

    // Public Scope...
    var pub = {};
    pub.$actionControl = $control;
    pub.$callout = $callout;

    pub.bindToControlClick = function () {
        pub.$actionControl.click(function (e) {
            e.preventDefault();
            e.stopPropagation();

            toggleCallout();                
        });
    }

    // Private Scope...
    function init() {
        // The callout-content subdiv is necessary for other operations that are
        // likely not relevant to the problem I am encountering.
        if($callout.children('.callout-content').length == 0)
            $callout.wrapInner('<div class="callout-content" />');
    }

    function toggleCallout() {
        if(pub.$callout.is(':hidden')) {
            // Show is actually more complicated than this, but that's not the problem.
            pub.$callout.show();
        } else {
            pub.$callout.hide();
        }
    }

    return pub;
};

问题在于,虽然标注最初是从视图中隐藏的,并且在单击时显示,但尝试切换标注会失败。当我在Chrome调试器中为$callout.is(':hidden')添加断点和观看值时,即使该元素可见,监视值也会评估为true

基于jQuery's entry for the :hidden selector,似乎在任何给定时间都会检查一些属性,这使我进入问题:我的设置中有什么能够愚弄jQuery的:hidden选择器始终认为标注是隐藏的,即使这种情况不再如此?

编辑:由于我在旁边小组中发现了我最近的一个问题,我的团队已经确保我们的应用程序在IE9标准模式下运行,所以环境应该不是一个问题。

编辑2:Fiddle of the problematic code(更新!问题全部转载。)

2 个答案:

答案 0 :(得分:2)

请尝试使用hasClass

function toggleCallout() {
    if(pub.$callout.hasClass('hidden')) {
        pub.$callout.removeClass('hidden');
    } else {
        pub.$callout.addClass('hidden');
    }
}

或者更快toggleClass

function toggleCallout() {
    pub.$callout.toggleClass('hidden');
}

另外请务必在使用前提出MyCallout声明,否则会出现错误

  

未捕获的TypeError:undefined不是函数

致电

var callout = new MyCallout($link, $callout);

工作 Fiddle

答案 1 :(得分:0)

问题实际上是一个CSS问题 - 虽然我的代码是理智的(正如我的OP中的jsFiddle所示),.callout div正在使用width: 0; height: 0的默认维度进行渲染,这会导致{{1选择元素。

我所要做的就是添加以下CSS来解决我的问题:

:hidden

课程:始终检查元素!什么看起来像一个脚本错误,实际上可能完全是另一回事。