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

IT技术 javascript html
2021-03-14 23:21:42

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

当然,我们总是会发现自己处于这样的情况:一个巧妙的内联 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分钟后,这是一个可怕的,可怕的想法我可以攻击整个股利(或任何) 并且我在页面的其余部分没有一堆神秘的 JS 和 CSS 杂物,从而稍微减慢了渲染速度。这类似于引用局部性的概念,但我们关注的是错误和代码膨胀,而不是缓存未命中。

6个回答

您几乎正确,但您没有考虑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>
我如何event用内联传播onclick='myFunction(event)'
2021-04-20 23:21:42
脚本必须在标签之后,否则在执行时标签不存在——我建议更改您的答案以反映这一点。
2021-04-24 23:21:42

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

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

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

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

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

啊。因此,我实际上可以使用该变量从我的内联 JS 代码段中event检索事件(以及通过它从中获取的原始元素event.target)!凉爽的。
2021-04-25 23:21:42
IE 确实不传递event参数,但是如果您event在此匿名函数中使用,IE 会将其理解为实际的事件对象。由于匿名函数window在 IE 中被设置为对象的属性,因此它会将其视为window.event.
2021-04-25 23:21:42

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

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

这是一个正确有效的论据,我同意。我自己通常不会添加内联脚本,也不会为该材料添加样式。但是人们有不同的口味。例如很多人喜欢在正文部分添加脚本和样式标签,我受不了。但它是有效的,有些人喜欢它。接缝bad practice/spaghettification对某些人来说是什么good practice/structure对其他人来说也是如此。
2021-04-23 23:21:42
我一直在查看github.com/styled-components/styled-components,例如,如果您将其与React结合使用,我们现在可以将与您的应用程序组件相关的所有内容都实际生活在一起(希望和平地)在一个地方。而且它实际上看起来也不可怕。感觉有进步。从这个角度来看,将内联样式和代码塞入 HTML 并不是正确的方法(到目前为止,似乎是将 HTML 和样式塞入了 JS 代码)。
2021-04-26 23:21:42
是的,我倾向于同意,我什至提供了合理的“理由”,说明为什么在某些情况下这种特殊的内联代码使用是合理的。但现实情况是,当应用程序(网络应用程序或其他应用程序)变得具有一定的复杂性时(这甚至通常不会花费太多时间或工作来实现),散布在 HTML布局中的少量代码片段很可能会导致从可维护性的角度来看,在架构上是不健全的。例如,甚至开始直接在 HTML 文件中编写 JS 代码,就很容易被意大利面化的滑坡所吸引。
2021-04-30 23:21:42

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

<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')
}

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

我不确定我们是否同意“很好地构建代码”的想法。如果您将 UI 绑定到核心功能实际所在位置的“核心功能”,在我看来,这似乎是一种比将它们绑定在 UI 中更糟糕的耦合安排。我通常将所有 UI 绑定内容与核心内容分开,我觉得 OP 也可能......
2021-04-24 23:21:42
我认为类似的东西<button onclick="login()"> test login </button>非常适合原型设计。您想立即测试需要用户交互的内容,但无论如何您都将在稍后将其删除。为什么要到处写额外的代码?
2021-04-26 23:21:42
这不是额外的代码,只是一个额外的匿名函数。而且它并不是到处都是,它实际上都在一个地方,在脚本标签中。
2021-05-10 23:21:42

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

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

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

你到底为什么要.....啊没关系,正如你提到的,这确实是被广泛采用的坏习惯:)