136

我知道这是不好的做法。如果可能的话,不要写这样的代码。

当然,我们总是会发现自己处于一个巧妙的内联 Javascript 片段可以快速解决问题的情况。

我追求这个查询是为了充分理解写这样的东西时会发生什么(以及潜在的陷阱):

<a href="#" onclick="alert('Hi')">Click Me</a>

据我所知,这在功能上与

<script type="text/javascript">
   $(function(){ // I use jQuery in this example
       document.getElementById('click_me').onclick = 
           function () { alert('Hi'); };
   });
</script>
<a href="#" id="click_me">Click Me</a>

由此推断,似乎分配给属性的字符串onclick被插入到一个匿名函数中,该函数被分配给元素的点击处理程序。真的是这样吗?

因为我开始做这样的事情:

<a href="#" onclick="$(this).next().fadeIn(); return false;">Display my next sibling</a> <!-- Return false in handler so as not to scroll to top of page! --> 

哪个有效。但我不知道这是多少黑客行为。它看起来很可疑,因为没有返回明显的函数!

你可能会问,你为什么要这样做,史蒂夫?内联 JS 是不好的做法!

老实说,我已经厌倦了仅仅为了修改页面的一个部分而编辑三个不同的代码部分,尤其是当我只是制作原型以查看它是否可以工作时。元素中定义与此 HTML 元素特别相关的代码要容易得多,有时甚至是有意义的:当我在 2 分钟后决定这是一个可怕的、可怕的想法时,我可以核对整个 div(或其他) 并且我没有在页面的其余部分挂起一堆神秘的 JS 和 CSS 杂物,从而稍微减慢了渲染速度。这类似于引用局部性的概念,但我们关注的是错误和代码膨胀,而不是缓存未命中。

4

7 回答 7

101

您已经得到了几乎正确的结果,但是您还没有考虑this提供给内联代码的值。

<a href="#" onclick="alert(this)">Click Me</a>

实际上更接近:

<a href="#" id="click_me">Click Me</a>
<script type="text/javascript">
document.getElementById('click_me').addEventListener("click", function(event) {
    (function(event) {
        alert(this);
    }).call(document.getElementById('click_me'), event);
});
</script>

内联事件处理程序设置this为等于事件的目标。您还可以在内联脚本中使用匿名函数

<a href="#" onclick="(function(){alert(this);})()">Click Me</a>
于 2012-05-15T20:04:01.133 回答
9

当你有浏览器时,浏览器会做什么

<a onclick="alert('Hi');" ... >

是将“onclick”的实际值设置为有效的值,例如:

new Function("event", "alert('Hi');");

也就是说,它创建了一个需要“事件”参数的函数。(嗯,IE 没有;它更像是一个简单的匿名函数。)

于 2012-05-15T19:59:55.987 回答
9

事件处理程序属性似乎有很多不好的做法。不好的做法是不知道并在最合适的地方使用可用的功能。事件属性完全是 W3C 文档化的标准,它们没有什么不好的做法。这与放置内联样式没有什么不同,这也是 W3C 记录的并且有时会很有用。无论您是否将其包裹在脚本标签中,都会以相同的方式进行解释。

https://www.w3.org/TR/html5/webappapis.html#event-handler-idl-attributes

于 2016-02-15T01:11:41.467 回答
6

回答您的问题的最佳方式是亲眼目睹

<a id="test" onclick="alert('test')"> test </a> ​

在js中

var test = document.getElementById('test');
console.log( test.onclick ); 

正如您在 中看到的console,如果您使用的是 chrome,它会打印一个带有传入事件对象的匿名函数,尽管它在 IE 中有点不同。

function onclick(event) {
   alert('test')
}

我同意你关于内联事件处理程序的一些观点。是的,它们很容易编写,但我不同意您关于必须在多个地方更改代码的观点,如果您的代码结构良好,则不需要这样做。

于 2012-05-15T20:19:44.397 回答
3

它看起来很可疑,因为没有返回明显的函数!

它是一个匿名函数,已附加到对象的单击事件。

你为什么要这样做,史蒂夫?

你到底为什么要这样做.....啊,没关系,正如你所提到的,这确实是被广泛采用的不良做法:)

于 2012-05-15T19:57:41.247 回答
3

在控制台中试试这个:

var div = document.createElement('div');

div.setAttribute('onclick', 'alert(event)');

div.onclick

在 Chrome 中,它显示了这一点:

function onclick(event) {
  alert(event)
}

...以及is的非标准name属性。div.onclick"onclick"

因此,这是否匿名取决于您对“匿名”的定义。与类似的东西比较var foo = new Function(),其中foo.name是一个空字符串,并且foo.toString()会产生类似的东西

function anonymous() {

}
于 2012-05-15T20:23:49.507 回答
0

使用javascript:

这里使用了输入元素

<input type="text" id="fname" onkeyup="javascript:console.log(window.event.key)">

如果要使用多行代码,请在javascript之后使用花括号:

<input type="text" id="fname" onkeyup="javascript:{ console.log(window.event.key); alert('hello'); }">
于 2021-02-11T11:00:54.253 回答