【问题标题】:Why can't the onclick handler be set to a native function? [duplicate]为什么不能将 onclick 处理程序设置为本机函数? [复制]
【发布时间】:2019-03-18 21:59:37
【问题描述】:

当一个元素的 onclick 事件处理程序直接设置为另一个元素的内置函数 click 时,即使在使用用户定义的中间函数时该事件也可以正常触发,该事件也无法触发。

同样,当 onclick 事件处理程序直接设置为内置函数 alert 时,即使它在使用用户定义的中间函数时也可以工作,但它会导致 TypeError: Illegal invocation

奇怪的是,当 onclick 事件处理程序直接设置为 console.log 时,它按预期工作,尽管这也是一个内置函数。

clickalert 发生了什么导致直接赋值行为异常?为什么添加一个简单地转发调用的匿名函数会有什么不同?

const div1 = document.getElementById("1");
const div2 = document.getElementById("2");
const div3 = document.getElementById("3");
const div4 = document.getElementById("4");
const div5 = document.getElementById("5");
const div6 = document.getElementById("6");
const indicator = document.getElementById("indicator");

indicator.onclick = function() {
  if (indicator.style.background == "blue") {
    indicator.style.background = "green";
  } else {
    indicator.style.background = "blue";
  }
};

div1.onclick = function(event) {
  indicator.click(event);
};

div2.onclick = indicator.click;

div3.onclick = function(event) {
  alert(event);
};

div4.onclick = alert;

div5.onclick = function(event) {
  console.log(event);
};

div6.onclick = console.log;
#indicator {
  height: 100px;
  width: 100px;
}
div {
  cursor: pointer;
  text-decoration: underline;
}
<div id="1">Set indicator color via function (works)</div>
<div id="2">Set indicator color directly (silently fails)</div>
<div id="3">Trigger alert via function (works)</div>
<div id="4">Trigger alert directly (fails with error)</div>
<div id="5">Trigger console log via function (works)</div>
<div id="6">Trigger console log directly (works)</div>
<div id="indicator"></div>

【问题讨论】:

  • 我不知道你到底想做什么......我有一种感觉,我不是唯一一个。
  • alert() 是一种方法。 message 参数可以为空,但如果没有括号,您不会调用该函数,而是对该函数的引用。这个问题解释得很好:stackoverflow.com/questions/35949554/…
  • @epascarello 我最初编写代码div2.onclick = indicator.click; 就是为了做到这一点:当单击另一个DOM 元素时触发对另一个DOM 元素的单击。我很困惑为什么如果不将它包装在另一个函数中它就不能工作,这就是我问这个问题的原因。我还尝试对其他内置函数(alertconsole.log)进行一些调查,但并未对情况有所了解。

标签: javascript


【解决方案1】:

你不能这样调用 alert,因为它不再在窗口的上下文中执行。它在您单击的 div 的上下文中执行。使用绑定,您可以将上下文更改回窗口,它会起作用。

const div4 = document.getElementById("4");

div4.onclick = alert.bind(window);
#indicator {
  height: 100px;
  width: 100px;
}
div {
  cursor: pointer;
  text-decoration: underline;
}
&lt;div id="4"&gt;Trigger alert directly (fails with error)&lt;/div&gt;

【讨论】:

  • 谢谢!我忘了简单地指定 indicator.clickwindow.alert 不会导致它绑定,并且无论调用实际发生在哪里,绑定都会在不同的上下文中发生。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-19
相关资源
最近更新 更多