如何正确推迟DOM元素更改,直到jQuery中的事件处理程序执行为止



foo.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
    <table>
        <tr>
            <td id="tdTxtBox"><input type="text" id="txtBox"/></td>
            <td id="tdChkBox"><input type="checkbox" id="chkBox"/></td>
        </tr>
    </table>
<script src="foo.js"></script>
</body>
</html>

foo.js

$('#txtBox').on('blur', function(){
    console.log('came out of text box');
});
$('#chkBox').on('click',function(){
    console.log('checked check box');
});

普通流:在文本框中输入一个值,单击复选框,该复选框实际上在文本框上触发了" Blur",并且在复选框上"单击"。这输出:

came out of text box
checked check box

在更改 foo.js 喜欢:

$('#txtBox').on('blur', function(){
    console.log('came out of text box');
    $('#tdChkBox').html('<input type="checkbox" id="chkBox"/>');
});
$('#chkBox').on('click',function(){
    console.log('checked check box');
});

此输出:

came out of text box

这是有道理的,因为在blur上,我实际上用另一组DOM元素重置#tdChkBox,jQuery丢失了复选框的凸起事件click(这是正确的理解吗?(

我在SO帖子中找到了这个问题的修复程序,以使用setTimeout推迟HTML的更改,这将使click事件处理程序像这样执行:

foo.js

$('#txtBox').on('blur', function(){
    console.log('came out of text box');
    setTimeout(function(){
        $('#tdChkBox').html('<input type="checkbox" id="chkBox"/>');
    },100);
});
$('#chkBox').on('click',function(){
    console.log('checked check box');
});

这是问题所在,setTimeout 100 MS可行,但 0 ms不起作用。显然,系统需要时间 t 提高点击事件并将其注册到 jQuery事件队列。分配给setTimeout的时间必须大于 t

此解决方案不是充分证明。如果明天需要多于 100 MS怎么办?如果我增加了这次,以便说 1000 ms,它的可用性命中率。

如何正确解决此问题?这里的理解是正确的还是我错过了一些基本的东西?

如果这是标准的jQuery/javaScript问题,有人可以指向我的方向正确。

尝试使用 mousedown试试,然后单击blur之前执行。Blurmouseup上运行,这意味着单击已完成

$('#txtBox').on('blur', function(){
    console.log('came out of text box');
});
$('#chkBox').on('mousedown',function(){
    console.log('checked check box');
});

工作示例

$('#txtBox').on('blur', function() {
  console.log('came out of text box');
});
$('#chkBox').on('mousedown', function() {
  console.log('checked check box');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <td id="tdTxtBox"><input type="text" id="txtBox" /></td>
    <td id="tdChkBox"><input type="checkbox" id="chkBox" /></td>
  </tr>
</table>

最新更新