为什么jQuery选择事件监听器多次触发?

时间:2016-03-29 12:26:43

标签: javascript jquery html google-chrome dom

请在Google Chrome浏览器中运行this sample

Stack Snippet

$(function() {
  $(":input").select(function() {
    $("div").text("Something was selected").show().fadeOut(1000);
    alert("Selected");
  });
  $("button").click(function() {
    $(":input").select();
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<button>Click To Select</button>
<input type="text" value="Some text">
<div></div>

为什么jQuery select事件监听器会多次触发?有谁知道这背后的原因?有没有使用超时的解决方法?

3 个答案:

答案 0 :(得分:14)

$(":input")选择器也在选择按钮,因此会导致递归。只使用$("input")$(":input:not(button)")

我注意到当三个事件被触发时,第一个没有originalEvent属性,所以我们绝对可以忽略它,而后两个有非常相似(但不相同)的时间戳。您可以将最后一个时间戳存储在某个变量中,并在事件监听器中将其与事件的时间戳进行比较。如果这两者的舍入值相同,则可以忽略此事件。

$(function() {
  var lastTimeStamp;
  $("input").select(function(event) {
    if (!event.originalEvent ||
        lastTimeStamp === Math.round(event.timeStamp)) return;
    lastTimeStamp = Math.round(event.timeStamp);
    $("div").text("Something was selected").show().fadeOut(1000);
    alert("Selected");
  });
  $("button").click(function() {
    $("input").select();
  });
});

请参阅updated JS Fiddle

答案 1 :(得分:10)

问题似乎是:

的组合
  • :input选择器获取inputbutton,因此会触发多个事件。
  • 即使仅使用input作为选择器,也会在相关元素上触发一些奇怪的事件传播,这会多次引发select事件处理程序。

要避免上述两种情况,请使用input作为选择器,并在事件处理程序中使用preventDefault()。可能还需要stopPropagation(),具体取决于您的HTML结构。

$(function() {
    $('input').select(function(e) {
        // e.stopPropagation(); // optional
        e.preventDefault();
        $('#message').text("Something was selected").show().fadeOut(1000);
        console.log('Selected');
    });

    $('button').click(function() {
        $('input').select();
    });
});

Working example

答案 2 :(得分:0)

更新:我们都被愚弄了。 select()函数需要一个防止默认值。

Rory McCrossan明白了这一点。做得好的伙伴。

顺便说一下,我不确定select()实际上有什么好处!像focus()或on('focus')之类的东西可能更有意义。但不确定上下文是什么。以下内容仍然如下:

为什么要浪费时间使用可能会改变的通用标签/类型选择器?使用ID,只选择你想要的ID。

如果要检测多个,请使用类。如果您想使用多个,但要确定您单击了哪一个,请使用类和ID。与班级绑定,并使用$this.attr('id')进行识别。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<button>Click To Select</button>
<input type="text" value="Some text" id="pick-me">
<div></div>
$(function() {
  $("#pick-me").select(function(event) {
    event.preventDefault();
    $("div").text("Something was selected").show().fadeOut(1000);
    alert("Selected");
  });
  $("button").click(function() {
    $("#pick-me").select();
  });
});