内联Javascript(HTML)如何工作?

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

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

为了充分理解发生了什么(以及潜在的陷阱),我正在追求这个问题:

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

据我所知,这在function上是一样的

 <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的string被插入到分配给该元素的点击处理程序的匿名函数中。 这是真的吗?

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

 <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! --> 

哪个工作。 但是我不知道这是多less。 它看起来可疑,因为没有明显的function正在返回!

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

说实话,我已经厌倦了编辑代码的三个不同部分,只是为了修改一个页面的一部分,特别是当我只是做一些原型来看看它是否可以工作的时候。 这是非常容易的,有时甚至是有道理的,特别是与这个HTML元素相关的代码在元素中定义:当我决定2分钟后,这是一个可怕的,可怕的想法,我可以nuke整个div(或任何),而且在页面的其余部分,我没有一堆神秘的JS和CSS cruft,减慢渲染的速度。 这与引用的局部性的概念类似,但是我们正在寻找错误和代码膨胀,而不是caching未命中。

你已经知道它几乎是正确的,但你没有考虑到提供给内联代码的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> 

内联事件处理程序将其设置为等于事件的目标。

浏览器做什么,当你有

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

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

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

也就是说,它创build了一个需要“事件”参数的函数。 (那么,IE浏览器不,它更像一个简单的匿名函数。)

事件处理程序属性周围似乎有很多不好的做法 。 糟糕的做法是不知道和使用最合适的可用function。 事件属性完全是W3Clogging的标准,对它们没有任何不好的做法。 这与embedded式样式没有什么不同,这也是W3Clogging的,并且有时可能有用。 无论你是否将它放在脚本标记中,它都将以相同的方式进行解释。

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

它看起来可疑,因为没有明显的function正在返回!

这是一个已经附加到对象的点击事件的匿名函数。

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

为什么地球上你是啊…啊,没关系,正如你所说,这是真的被广泛采用不好的做法:)

回答你的问题的最好方法是看到它的行动。

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

在js中

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

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

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

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

在控制台中试试这个:

 var div = document.createElement('div'); div.setAttribute('onclick', 'alert(event)'); div.onclick 

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

 function onclick(event) { alert(event) } 

…和div.onclick的非标准name属性是"onclick"

所以,这是否是匿名取决于你的“匿名”的定义。 比较像var foo = new Function() ,其中foo.name是一个空string,而foo.toString()会产生类似于

 function anonymous() { }