如何在更改事件处理程序中追加后获取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’,当我编辑输入时,请单击我看到的跨度:
- 跨度上的mousedown
- 改变输入
- 鼠标跨度
- 点击跨度
但是,通过更改事件处理程序中的追加,我看到:
- 跨度上的mousedown
- 改变输入
- 鼠标输入
在后一种情况下,mousedown和mouseup事件具有相同的坐标(如果我小心不要在单击时移动鼠标):它们都是span元素边界内和输入元素外部的坐标。 尽管如此,在Firefox和Chrome中,mouseup与输入元素而不是span元素相关联。
所以,我的问题变成:为什么mouseup事件与input元素而不是span元素相关联,当它的坐标在span元素的范围内而不在input元素的范围内时?
可以有许多解决此问题的解决方法。 这完全取决于UI演示。 根据设计,您也可以考虑其他解决方法。 截至目前,我可以想到可以解决这个问题的三件事:
-
给你的警报div一个高度,使其垂直滚动。 这样做可以防止您的跨度位置发生变化并触发两个事件。 例如
div> -
或者您可以稍微更改您的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'); }); }); -
或者上述任何一个都不适合你,那么你可以设计你的跨度并给它一定的宽度和高度,这样即使在追加警告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( '点击'); }); });