如何在更改事件处理程序中附加后获取jQuery点击事件 [英] How to get jQuery click event after append in change event handler

查看:139
本文介绍了如何在更改事件处理程序中附加后获取jQuery点击事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下文件:

 <!DOCTYPE html> 
< html>
< head>
< meta http-equiv =content-typecontent =text / html; charset = UTF-8>
< meta charset =UTF-8>
< title>测试< / title>
< script src =https://code.jquery.com/jquery-2.1.1.js>< / script>
< / head>
< body>
< div id =alert>< / div>
< input type =textid =input>< / br>
< span id =span> Span< / span>

< script>
$(function(){
$('#input')。on('change',function(){
console.log('change');
$ ('#alert')。append('< div> An alert< / div>');
});
$('#span')。on('click' ){
console.log('click');
});
});
< / script>
< / body>
< / html>

点击跨度,点击事件处理程序运行。



更改输入,更改事件处理程序运行。



更改输入并单击跨度(没有其他离开输入 - 例如没有标签出来,运行更改事件处理程序,但点击事件处理程序不会运行。



如果我从更改事件处理程序中删除附加信息,则更改输入和点击跨度,两个事件处理程序都会运行,所以附件会以某种方式干扰点击事件。



如何在更改事件处理程序后获取点击事件触发附加元素?



这是引发问题的最小代码。在实际情况下,有多个输入,跨度被设计为看起来像一个按钮。输入上的更改事件处理程序验证值,如果无效则添加警报。通常,输入改变而不用点击跨度/按钮,但编辑一个输入,然后点击跨度/按钮,而输入焦点仍然在一个输入是可能的,在这种情况下,我希望两个事件处理程序运行。



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



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

  mousedown 
mouseup
点击

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


  1. mousedown on span

  2. 更改输入

  3. mouseup on span

  4. 点击span

但是,随着更改事件处理程序中的追加,我看到: p>


  1. mousedown on span

  2. 更改输入

  3. mouseup on输入

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



所以,我的问题变成:为什么mouseup事件与输入元素而不是跨度元素,当它的坐标在span元素的边界内并且不在输入元素的边界内时?

解决方案

可以有多种解决方法来处理此问题。它完全取决于UI演示。根据设计,您也可以考虑其他解决方法。到目前为止,我可以想到三件可以做的事情来处理这个问题:


  1. 给你的警报div一个高度并使其垂直滚动。这样做会阻止您的跨度的位置更改并触发这两个事件。例如

    < div id =alertstyle =height:100px; overflow-y:scroll;>< / div> pre> 

  2. 或者您可以更改您的JavaScript一点,以满足您的目的。以下是代码片段(修改意见),以满足您的需要。

      $(function(){
    var isMouseDownOnSpan = 0; //添加标志变量以跟踪用户是否点击跨度
    $('#input')。on('change',function(){
    console.log更改');
    $('#alert')。append('< div>一个警报< / div>');
    //如果用户尝试点击跨度,然后触发点击事件手动
    if(isMouseDownOnSpan){
    $('#span')。trigger('click');
    }
    });

    //绑定mousedown事件并设置标志值为true确保用户点击跨度
    $('#span')。on('mousedown',function(e){
    isMouseDownOnSpan = 1;
    });

    $('#span')。on('click',function(){
    isMouseDownOnSpan = 0; //重置标志值一旦点击事件被触发。
    c onsole.log('click');
    });
    });那么你可以设计自己的跨度,并给出一定的限制。宽度和高度,即使在附加警报div之后,用户的鼠标也在跨度范围内。我知道这不能是一个永久的解决方案,但它仍然可以最小化现实生活中的错误变化。 ;)



I have the following document:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta charset="UTF-8">
    <title>Test</title>
    <script src="https://code.jquery.com/jquery-2.1.1.js"></script>
</head>
<body>
    <div id="alert"></div>
    <input type="text" id="input"></br>
    <span id="span">Span</span>

<script>
    $(function() {
        $('#input').on('change', function() {
            console.log('change');
            $('#alert').append('<div>An alert</div>');
        });
        $('#span').on('click', function() {
            console.log('click');
        });
    });
</script>
</body>
</html>

Click on the span and the click event handler runs.

Change the input and the change event handler runs.

Change the input and click on the span (without otherwise leaving the input - e.g. no tab out and no click elsewhere) and the change event handler runs but the click event handler does not run.

If I remove the append from the change event handler, then change the input and click on the span, both event handlers run, so the append is interfering with the click event somehow.

How can I get the click event to fire after the change event handler appends the elements?

This is minimal code to elicit the problem. In the real case there are multiple inputs and the span is styled to look and behave like a button. The change event handlers on the inputs validate the values, adding an alert if they are invalid. Commonly, inputs are changed without clicking the span/button but editing an input then clicking the span/button while input focus is still on an input is possible, in which case I want both event handlers to run.

On further investigation, I see that the problem is in how events are generated.

Per DOM Level-2: The click event occurs when the pointing device button is clicked over an element. A click is defined as a mousedown and mouseup over the same screen location. The sequence of these events is:

mousedown
mouseup
click

Without the 'append' in the change event handler, when I edit the input then click on the span I see:

  1. mousedown on span
  2. change on input
  3. mouseup on span
  4. click on span

But, with the append in the change event handler I see:

  1. mousedown on span
  2. change on input
  3. mouseup on input

In the latter case, the mousedown and mouseup events have the same coordinates (if I am careful not to move the mouse while clicking): they are both coordinates within the bounds of the span element and outside the input element. None the less, in Firefox and Chrome the mouseup is associated with the input element rather than the span element.

So, my question becomes: why is the mouseup event associated with the input element rather than the span element, when its coordinates are within the bounds of the span element and not within the bounds of the input element?

解决方案

There can be a number of workarounds to deal with this issue. It totally depends on the UI presentation. Depending on the design you can think of other workarounds as well. As of now I can think of three things which can be done to deal with the issue:

  1. Give your alert div a height and make it vertically scroll-able. Doing this will prevent your span's position change and would trigger both the events. e.g

     <div id="alert" style="height: 100px; overflow-y: scroll;"></div>

  2. Or you can change your javascript a little to meet your purpose. Below is the code snippet (comments amended) with changes to meet your need.

    $(function() {
        var isMouseDownOnSpan = 0;  // flag variable added to track whether user clicked on the span.
        $('#input').on('change', function() {
            console.log('change');
            $('#alert').append('<div>An alert</div>');
            // 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. OR else none of the above suits you then you can design your span and give it certain width and height such that the user's mouse is within the span boundaries even after the alert div is appended. I know this can't be a permanent solution but still it can minimize the changes of error in real life scenarios. ;)

这篇关于如何在更改事件处理程序中附加后获取jQuery点击事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆