Click事件函数执行两次

时间:2016-01-23 14:36:28

标签: javascript jquery

我对这段代码的结果感到困惑。在我看来,$("#title")的内容是"你好"并单击,它执行函数saygoodbye()并添加一个新的单击事件匿名函数。它获得外部警报。当内容是"再见"并且单击,这两个函数都应该执行。它应该获得一个外部警报和 ONE 内部警报。

但事实上,我得到一个外部警报和两个内部警报。 另一个内心警报来自哪里?



var count = 0;
function saygoodbye(){
  alert("ok is outer");
  $("#title").html("goodbye");
  $("#title").click(function() {
    alert("ok is inner");
    $('#title').html("hello");
    $('#title').off("click");
  });
}

<script src="//code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script>

<h1 id="title" onclick="saygoodbye();">hello</h1>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:5)

  1. 第一次点击“saygoodbye”运行时,发布“外部”警报,并建立点击处理程序。
  2. 第二次点击,“saygoodbye”再次运行,发布“外部”,并建立另一个点击处理。
  3. 然后由jQuery处理“click”事件,此时此处有两个你的“点击”处理程序。
  4. 当你致电.click()时,你总是会添加一个新的处理程序;以前添加的处理程序不会被删除。当您致电.off()时,它们将被删除,但直到已经连接了两个处理程序才会发生这种情况。库(jQuery)维护处理程序列表并使用它自己的内部事件处理程序来实际处理来自浏览器的事件。因此,即使只有两个真正的“单击”事件,当调用jQuery处理程序时,有两个jQuery注册的处理程序供库调用。

    通常,在其他事件处理程序中添加事件处理程序是一种可疑的处理方式。它不完全是错误的,但它增加了复杂性。在这里,您可以使用两种不同的技术来注册事件处理程序。 “saygoodbye”函数附加到DOM元素的“onclick”属性。但是,jQuery代码使用DOM API attachEventHandler()来注册处理程序。这两种机制是分开的。当发生“点击”时,浏览器将首先检查“onclick”属性,然后调用通过API注册的任何处理程序。

答案 1 :(得分:2)

这是因为事件是从DOM注册的。动态注册,然后它工作。

从标记中删除onclick属性。

var count = 0;

$('#title').click(saygoodbye);

function saygoodbye(){
  alert("ok is outer");
  $("#title").html("goodbye");
  $("#title").click(function() {
    alert("ok is inner");
    $('#title').html("hello");
    $('#title').off("click");
  });
}
<script src="//code.jquery.com/jquery-2.1.4.min.js" type="text/javascript"></script>
<h1 id="title">hello</h1>

阅读此SO帖子,了解为什么要随时注册事件(对于您的情况)。 jQuery.click() vs onClick

修改

首先,为了解除通过元素属性触发的事件,我们需要使用

document.getElementById("title").onclick = null;

其次,jQuery的.off()函数只会取消绑定由jQuery .on()

添加的处理程序
  

http://api.jquery.com/off/

上的文档      
      
  • “。off()方法删除附加了.on()
  • 的事件处理程序   
  • .click() - 是.on()
  • 的简写方法   

所以saygoodbye()并没有逃脱,这是调试。

点击标题。(标题为你好)

  1. 调用goodbyefunction alert'external';
  2. 将html更改为'goodbye'assign
  3. 新的标题处理程序(点击事件)。
  4. 点击标题(告别标题)

    1. call goodbyefunction
    2. alert'external';
    3. 将html更改为'goodbye'(是的 再次改变)
    4. 为title赋予另一个事件匿名处理程序(请参阅 附加1个处理程序)
    5. 致电匿名处理程序1
    6. alert'inner'
    7. 虽然在这个阶段(.off()函数被指定。这只会 如果所有事件都被触发则执行);
    8. 致电匿名处理程序2
    9. alert'inner'
    10. .off()功能在这里起作用并杀死额外的2 处理程序。
    11. 希望这种细分有所帮助。