3

有两个input元素隐藏在模糊中。问题是,如果单击是在元素被隐藏在 DOM 之后的元素上,则导致模糊的单击事件会丢失。

如果单击的元素在模糊元素之前,它会按预期工作

这个简单的片段演示了:

<html>
<script src="./jquery.min.js" ></script>
<script type="text/javascript">
$(document).ready(function() {
        $('input').blur(function(e) {
            console.log('blurred');
            $(this).hide();
        });

        $('.a').click(function() {
            console.log('div clicked');
        });

        $(document).click(function() {
            console.log('doc clicked');
        });
    });
</script>
<body>
<div id="div1">
<div class="a"><input /></div>
<div class="a"><input /></div>
</div>
</body>
</html>

如果单击底部输入,然后单击顶部,它会按预期工作 - “模糊”打印,然后“div clicked”,然后“doc clicked”,底部输入被隐藏。

如果单击顶部输入,则隐藏顶部输入的底部,仅“模糊”打印,并且无法在任何地方处理单击事件。

如果调用 tohide被注释掉,它也可以按预期工作。

使用.live并没有什么不同。

我可以想办法解决这个问题,但没有一个很好。关于为什么inputs 的顺序很重要或更好的解决方案的任何想法?

谢谢。

4

3 回答 3

2

好的好的好的,这只是我们一起愚蠢。

看看当你从上到下点击时发生了什么。

顶部有焦点。当您单击位于其下方的第二个输入时,会在单击事件在第二个 div 上注册之前触发模糊事件。

发生的事情是您单击第二个输入以使其获得焦点。由于事件从单击的目标(第二个输入)冒泡,因此它获得焦点。但是由于第一个输入模糊事件首先触发,它会将顶部 div 的高度降低到 0,并立即将第二个 div 向上移动到当前鼠标位置范围之外。因此,第二个 div 上的点击事件永远不会发生,因为在此之前 div 已经被移开。

您可以在这个 jsfiddle 中看到原因。http://jsfiddle.net/Z884F/我添加了
元素来保持 div 的高度,即使它们的输入被隐藏。如果您查看控制台,您会发现它按预期工作。

Firefox 工作的原因是它处理事件的时间略有不同。

忽略我下面的原始答案:

这是非常奇怪的行为。我已经在 Mac OS 10.7 上的 Chrome 和 Safari 中验证了您的结果。但是,Firefox 12.0 可以按预期工作。

如果您在 500 毫秒 setTimeout 内进行模糊处理,它会按预期工作。虽然我认为父 div 上的事件仍在被删除。

我在这里有一个 jsfiddle,http://jsfiddle.net/gsuTw/

我强烈建议在 jQuery 开发网站上将此作为错误提交。这看起来像 blur() 的错误。

于 2012-09-25T05:51:58.910 回答
0

事件对象的srcElement属性是 IE 事件模型特有的。e.targetjQuery 通过添加where exists but not来“规范化”事件对象e.srcElement

    // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
    if ( !event.target ) {
        event.target = originalEvent.srcElement || document;
    }

所以在这一行:

>  $(e.srcElement).hide();

'e.srcElement` 返回 undefined 并且该语句什么也不做。

解决方法是更改e.srcElement​​为e.targetthis改为使用。

请注意,在侦听器中,this是调用侦听target器的元素,而 是调度原始事件的元素。因此,它们可能会或可能不会引用相同的元素。

在模糊侦听器中this === event.target,但不在点击侦听器中。

顺便说一句,将调用链接在一起被认为是一种不好的做法,因为它会使错误(像这样的错误)难以找到和调试。拥有一个默默地忽略此类错误的库会使它变得更加困难,请考虑:

    $('input').blur(function(e) {

        if (e.srcElement) {
          $(e.srcElement).hide();

        } else {
          // No e.srcElement? what now!!
        }
    });

防御性编码实践对 Web 开发人员来说是通行证,但它们更可靠且更易于调试。

于 2012-09-25T05:22:50.720 回答
0

我不认为这可以回答为什么事件被吞下。但如果输入的位置不是问题,您可以改为更改可见性。

$('input').blur(function(e) {
    console.log('blurred');
    $(this).css('visibility', 'hidden');
});
于 2012-09-25T06:32:17.737 回答