内联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() { }