如何在更改事件处理程序中追加后获取jQuery单击事件

我有以下文件:

     Test    

Span $(function() { $('#input').on('change', function() { console.log('change'); $('#alert').append('
An alert
'); }); $('#span').on('click', function() { console.log('click'); }); });

单击span并运行click事件处理程序。

更改输入并更改事件处理程序。

更改输入并单击跨度(不保留输入 – 例如没有标签输出,也没有单击其他位置)并且更改事件处理程序运行但单击事件处理程序不运行。

如果我从更改事件处理程序中删除append,然后更改输入并单击span,两个事件处理程序都会运行,因此append会以某种方式干扰click事件。

在更改事件处理程序附加元素后,如何触发click事件?

这是引发问题的最小代码。 在实际情况中,有多个输入,并且跨度的样式看起来和行为就像一个按钮。 输入上的更改事件处理程序validation值,如果它们无效则添加警报。 通常,输入在不单击范围/按钮的情况下进行更改,但编辑输入然后单击范围/按钮,同时输入焦点仍在输入上,在这种情况下,我希望两个事件处理程序都能运行。

在进一步调查中,我发现问题在于如何生成事件。

每个DOM Level-2:在元素上单击指针设备按钮时发生click事件。 单击被定义为同一屏幕位置上的mousedown和mouseup。 这些事件的顺序是:

 mousedown mouseup click 

如果没有更改事件处理程序中的’append’,当我编辑输入时,请单击我看到的跨度:

  1. 跨度上的mousedown
  2. 改变输入
  3. 鼠标跨度
  4. 点击跨度

但是,通过更改事件处理程序中的追加,我看到:

  1. 跨度上的mousedown
  2. 改变输入
  3. 鼠标输入

在后一种情况下,mousedown和mouseup事件具有相同的坐标(如果我小心不要在单击时移动鼠标):它们都是span元素边界内和输入元素外部的坐标。 尽管如此,在Firefox和Chrome中,mouseup与输入元素而不是span元素相关联。

所以,我的问题变成:为什么mouseup事件与input元素而不是span元素相关联,当它的坐标在span元素的范围内而不在input元素的范围内时?

可以有许多解决此问题的解决方法。 这完全取决于UI演示。 根据设计,您也可以考虑其他解决方法。 截至目前,我可以想到可以解决这个问题的三件事:

  1. 给你的警报div一个高度,使其垂直滚动。 这样做可以防止您的跨度位置发生变化并触发两个事件。 例如

      
  2. 或者您可以稍微更改您的JavaScript以满足您的目的。 以下是代码片段(已修改评论),其中包含更改以满足您的需求。

     $(function() { var isMouseDownOnSpan = 0; // flag variable added to track whether user clicked on the span. $('#input').on('change', function() { console.log('change'); $('#alert').append('
    An alert
    '); // If user tries to click on the span then trigger the click event manually. if(isMouseDownOnSpan){ $('#span').trigger('click'); } }); // Bind mousedown event and set the flag value true. This ensures that the user clicked on the span. $('#span').on('mousedown', function(e) { isMouseDownOnSpan = 1; }); $('#span').on('click', function() { isMouseDownOnSpan = 0; // Reset flag value once the click event is fired. console.log('click'); }); });
  3. 或者上述任何一个都不适合你,那么你可以设计你的跨度并给它一定的宽度和高度,这样即使在追加警告div后,用户的鼠标也在跨度边界内。 我知道这不是一个永久的解决方案,但它仍然可以最大限度地减少现实生活场景中的错误变化。 ;)

我保存了你的代码,然后在浏览器中运行它。 为什么你认为它没有? 你在检查控制台输出吗?

在你的更改事件处理程序中添加$(’#span’)。click()

 $(function() { $('#input').on('change', function() { console.log('change'); $('#alert').append('
An alert
'); $('#span').click(); }); $('#span').on('click', function() { console.log('click'); }); });

我弄清楚我的问题是什么:

当我添加到div时,文档布局会发生变化。 我将光标放在跨度上并按下鼠标左键。 这会导致输入失去焦点,从而触发更改事件。 change事件处理程序将一个div附加到#alert div。 这会将屏幕下方的所有内容推到屏幕下方。 然后我释放鼠标按钮,没有移动它。 但是鼠标不再超出范围 – 由于布局已更改,现在它已经超过了输入,因此mouseup事件将输入作为其目标,而不是跨度。

即使鼠标未移动,屏幕布局也已更改,因此鼠标已离开跨度并进入输入。 跨度看到mousedown没有mouseup,所以没有点击。 输入看到没有mousedown的mouseup,所以也没有点击那里。

我的错误是认为因为我没有移动鼠标,鼠标应该仍然在跨度上。

如果我在跨度之后放置警报div,那么编辑输入并单击跨度按预期工作,但这不是我想要的屏幕布局。

我想如果我将警报div留在顶部,我需要在更改事件处理程序中执行的操作是将消息添加到警报div,这将向下移动跨度,然后向下移动鼠标以使其仍然在跨度上。 然后,当用户释放鼠标按钮时,它仍将在跨度上,并且跨度可能(我希望)接收到单击事件。


      $(function(){
             $('#input')。on('change',function(){
                的console.log( '变更');
                 $('#alert')。append('一个警报',函数(){
                       $('#span')。on('click',function(){
                         的console.log( '点击');
                       });
                 });
             });
             $('#span')。on('click',function(){
                的console.log( '点击');
             });
         });