内联 Javascript (HTML)是如何工作的?

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

当然,我们总是会发现自己处于这样一种情况: 一个聪明的内联 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的字符串似乎插入到分配给元素的 click 处理程序的匿名函数中。真的是这样吗?

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

<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 残渣,这会稍微减慢渲染的速度。这类似于访问局部性的概念,但是我们看到的不是缓存错误,而是 bug 和代码膨胀。

572563 次浏览

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

它是一个附加到对象的 click 事件的匿名函数。

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

你究竟为什么要这样做... ... 啊,没关系,正如你所说的,这真的是被广泛采用的不良做法:)

浏览器会做什么

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

就是将“ onclick”的实际值设置为类似下面这样的有效值:

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

也就是说,它创建一个需要“ event”参数的函数。(IE 不是这样的,它更像是一个简单的匿名函数。)

您几乎完全正确,但是没有考虑到提供给内联代码的 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>

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

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

在 J 里面

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

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

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

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

在控制台中尝试这样做:

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是一个空字符串,而 foo.toString()将产生类似于

function anonymous() {


}

围绕事件处理程序属性似乎抛出了很多 坏习惯。不好的做法是不知道并在最合适的地方使用可用的特性。事件属性是完全 W3C 文档化的标准,没有什么不好的做法。它与放置内联样式没有什么不同,内联样式也是 W3C 文档,在某些时候非常有用。不管你是否将它包装在脚本标记中,它都会被以相同的方式解释。

Https://www.w3.org/tr/html5/webappapis.html#event-handler-idl-attributes

使用 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'); }">