Javascript 内联onclick是如何计算的?

Javascript 内联onclick是如何计算的?,javascript,html,Javascript,Html,我很好奇内联元素属性事件的内容在后台是如何工作的 我们从一个简单的函数开始 function handler(e) { console.log(e); } 用例1 如果要将此处理程序添加到按钮中,可以执行以下操作: <button onclick="handler();">Click Me</button> 我们点击登录:MouseEvent{…} 现在我们记录事件,正如我们所预料的那样 用例3 但是如果我们只指定函数名呢 <button onclick

我很好奇内联元素属性事件的内容在后台是如何工作的

我们从一个简单的函数开始

function handler(e) {
    console.log(e);
}
用例1

如果要将此处理程序添加到按钮中,可以执行以下操作:

<button onclick="handler();">Click Me</button>
我们点击登录:
MouseEvent{…}

现在我们记录事件,正如我们所预料的那样

用例3

但是如果我们只指定函数名呢

<button onclick="handler">Click Me</button>
它工作,捕获事件并记录相关的
事件
对象

结论性问题

无论我们传递给
onclick=”“
inline的文本/内容/语句是什么,它是否基本上在其上运行
eval()
?当我们在javascript中附加它时(
btn.onclick=…
),它会经过适当的过程来截获事件,然后调用有界处理函数并传递相应的事件对象(例如
MouseEvent

快速注释


要明确的是,这是一个信息丰富的问题,要理解基本原理,不管它被认为是好的还是坏的做法。这一点没有讨论。

是的,在内联处理程序中,属性文本本质上只是
eval
ed,并带有一些限定条件。什么

<button onclick="handler">Click Me</button>
这不会引发错误(因为
handler
是可引用的),但它也不会运行
handler
,因为您只是引用函数,而不是调用它

当你这样做的时候

btn.onclick = handler;
<button onclick="handler(event);">Click Me</button>
您正在将对
handler
的引用传递给
onclick
内部构件,单击按钮后,内部构件将调用该引用

(如果您执行了
btn.onclick=handler;
handler
将立即被调用,其返回值将作为侦听器添加,这不是您想要的)

当你这样做的时候

btn.onclick = handler;
<button onclick="handler(event);">Click Me</button>
在译员看来,有点像:

<a onclick="
  with(this) {
    search();
  }
">Click me!</div>
点击我!
这是有问题的,因为
search
htmlanchorement.prototype
的一个属性。如果这些变量名是元素原型链上任意位置的属性,那么引用其他变量名可能会有类似的问题


最好完全避免内联处理程序,而是使用Javascript正确地附加事件。

这并不是发生的事情,但您可以这样想象:

假设javascript引擎将
onclick
属性的内容保存为字符串,当用户单击该元素时,会对内容进行求值

例如:

btn.onclick = () => {
  handler;
};
函数foo(a,b){ 警报(a+“”+b); }
单击我
为事件使用HTML属性时,实际上是在引擎盖下创建了一个函数,该函数被指定为相关事件的处理程序

  • 函数的主体是属性的内容。它应该是JavaScript代码
  • 函数获取
    事件
    参数作为参数
另见

所以

在案例1中,生成的处理程序:

function handlerHtml(event) {
    handler()
}
function handlerHtml(event) {
    handler(event)
}
function handlerHtml(event) {
    handler
}
在案例2中,生成的处理程序:

function handlerHtml(event) {
    handler()
}
function handlerHtml(event) {
    handler(event)
}
function handlerHtml(event) {
    handler
}
在案例3中,生成的处理程序:

function handlerHtml(event) {
    handler()
}
function handlerHtml(event) {
    handler(event)
}
function handlerHtml(event) {
    handler
}

我不认为会发生这种情况——请记住,属性发生的事情并不简单。在用例3中,不会发生任何事情,因为onclick需要一点javascript来执行,而不是一个名称——所以发生的事情是“handler”被解释为一个变量名(就像你在.js文件中把它作为一个独立的行),它是未定义的,因此计算结果为false,不做任何操作。是的,
这确实很棘手,因为您可以在目标元素的原型链中触发查找。但你的回答似乎证实了我的怀疑。我的理论是,
onclick=“handler”
没有触发,因为它(在某种程度上)是“eval”行为。因此,它只有引用,但不“知道”调用被引用的东西(本例是一个函数)。我想我的直觉让我走上了正确的道路。在一些文档中还发现,参数需要“script”,这并不意味着它需要一个函数作为参数,而是实际需要一个脚本作为字符串来“eval”排序