修改DOM时,单击事件丢失

时间:2012-09-25 05:03:43

标签: javascript html

有两个input元素可以隐藏模糊。问题是,如果点击是在元素隐藏在DOM之后的元素上,那么导致模糊的click事件就会丢失。

如果点击的元素之前模糊元素,则按预期工作

这个简单的片段演示了:

<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”,底部输入被隐藏。

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

如果对hide的调用已被注释掉,它也会按预期运行。

使用.live没有任何区别。

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

感谢。

3 个答案:

答案 0 :(得分:2)

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

查看从上到下点击时发生的情况。

Top有焦点。当你点击它的第二个输入时,模糊事件会在点击事件在第二个div上注册之前触发

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

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

Firefox工作的原因是它以稍微不同的方式处理事件的时间安排。

IGNORE我原来的回答:

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

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

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

我强烈建议将此文件作为jQuery开发站点的错误提交。这看起来像一个模糊的错误()。

答案 1 :(得分:0)

事件对象的 srcElement 属性是IE事件模型所特有的。 jQuery通过添加e.target而不是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

'e.srcElement`返回undefined,语句不执行任何操作。

修复方法是将e.target更改为this或改为使用this

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

在模糊侦听器 $('input').blur(function(e) { if (e.srcElement) { $(e.srcElement).hide(); } else { // No e.srcElement? what now!! } }); 中,但不在点击侦听器中。

BTW,将调用链接在一起被认为是不好的做法,因为它会使错误(如此错误)很难找到和调试。拥有一个静默忽略此类错误的库会使其更难,请考虑:

{{1}}

防御性编码实践对Web开发人员来说很有用,但它们更可靠,更容易调试。

答案 2 :(得分:0)

我认为这并不能解释为什么事件会被吞噬。但是,如果输入的位置不是问题,则可以改变可见性。

$('input').blur(function(e) {
    console.log('blurred');
    $(this).css('visibility', 'hidden');
});