内联Javascript(在HTML中)如何工作?

Ste*_* Lu 121 html javascript html5

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

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

我正在追求这个问题,以便在完全理解发生这样的事情时会发生什么(以及潜在的陷阱):

<a href="#" onclick="alert('Hi')">Click Me</a>
Run Code Online (Sandbox Code Playgroud)

据我所知,这在功能上是相同的

<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>
Run Code Online (Sandbox Code Playgroud)

从这里推断,似乎分配给属性的字符串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! --> 
Run Code Online (Sandbox Code Playgroud)

哪个有效.但我不知道这是多少黑客.它看起来很可疑,因为没有明显的功能正在返回!

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

老实说,我已经厌倦了编辑三个不同的代码部分只是为了修改页面的一个部分,特别是当我只是原型化一些东西,看它是否会起作用.它是如此容易得多,有时甚至还为具体涉及到这个HTML元素的代码的含义来定义权范围内的元素:当我决定2分钟后,这是一个可怕的,可怕的想法我可以攻击整个股利(或任何并且我没有在页面的其余部分悬挂一堆神秘的JS和CSS残骸,减慢了渲染速度.这类似于引用局部性的概念,但我们正在查看错误和代码膨胀,而不是缓存未命中.

aps*_*ers 89

你已经几乎正确了,但你没有考虑this提供给内联代码的值.

<a href="#" onclick="alert(this)">Click Me</a>
Run Code Online (Sandbox Code Playgroud)

实际上更接近:

<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>
Run Code Online (Sandbox Code Playgroud)

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

<a href="#" onclick="(function(){alert(this);})()">Click Me</a>
Run Code Online (Sandbox Code Playgroud)

  • 脚本必须在标记之后,否则标记在执行时不存在 - 我建议更改您的答案以反映这一点. (7认同)

Poi*_*nty 8

你有什么浏览器做的

<a onclick="alert('Hi');" ... >
Run Code Online (Sandbox Code Playgroud)

是将"onclick"的实际值设置为有效的类似:

new Function("event", "alert('Hi');");
Run Code Online (Sandbox Code Playgroud)

也就是说,它创建了一个期望"event"参数的函数.(好吧,IE没有;它更像是一个简单的简单匿名函数.)

  • 啊.所以我实际上可以使用变量`event`从我的内联JS片段中检索事件(以及来自它的原始元素,通过`event.target`)!凉. (2认同)

Dan*_*l B 8

围绕事件处理程序属性似乎有很多不良做法.糟糕的做法是不了解并使用最合适的可用功能.事件属性完全是W3C文档标准,没有任何不良做法.这与放置内联样式没有什么不同,内联样式也是W3C记录的,并且可以在有时使用.无论您是否将其包装在脚本标签中,它都将以相同的方式进行解释.

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

  • 是的,我倾向于同意,我甚至提供了合理的"理由",为什么在某些情况下这种特定类型的内联代码的使用可能是合理的.但实际情况是,当一个应用程序(网络应用程序或其他)成为一定的复杂性(这通常不需要花费很多时间或努力达到)时,几乎没有关于HTML*布局的*代码*片段*从可维护性的角度来看,可能在架构上是不健全的.例如,即使开始直接在一个HTML文件中编写JS代码,人们也会想到一个滑动的斜坡. (2认同)

azi*_*ani 5

回答您的问题的最佳方法是查看它的实际应用。

<a id="test" onclick="alert('test')"> test </a> ?
Run Code Online (Sandbox Code Playgroud)

在js中

var test = document.getElementById('test');
console.log( test.onclick ); 
Run Code Online (Sandbox Code Playgroud)

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

function onclick(event) {
   alert('test')
}
Run Code Online (Sandbox Code Playgroud)

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