为什么内联事件处理程序属性在现代语义 HTML 中是个坏主意?

IT技术 javascript html events
2021-02-03 23:40:21

内联事件处理程序是否被认为是一种不好的做法?

例如: <button onclick=someFunction()>Click me!</button>

如果是这样,使用内联事件处理程序的缺点是什么?

3个回答

这是一个坏主意,因为...

  1. 最佳实践建议明确划分内容、风格和脚本。使用内联 JavaScript(或 CSS)混淆您的 HTML 与此不一致。

  2. 例如,您只能使用on*-style events绑定每种类型的一个事件,因此您不能有两个onclick事件处理程序。

  3. 如果内联指定事件,则 JS 将指定为字符串(属性值始终为字符串)并在事件触发时进行评估。评价是邪恶的。

  4. 您面临着必须引用命名函数的问题。这并不总是理想的(事件处理程序通常采用匿名函数)并且对需要全局访问的函数有影响

  5. 您的内容安全策略 (CSP) 必须(不明智地)扩展以允许评估的内联 JavaScript。

简而言之,通过专用addEventListenerAPI 或通过 jQuery 或其他方式集中处理事件

[2021 编辑]

如今,react式框架在某种程度上扭转了这一趋势。响应式框架中的事件通常被指定为属性,例如在 Vue 中:

<p v-on:click=foo>Hello</p>

... wherefoo是当前组件的数据对象的方法。

是的,但数据属性存储元。我并不反对,我只是说曾经有一段时间这个想法会受到很多人的质疑。然而,它们的用处超过了语义的关注。
2021-03-12 23:40:21
“曾经有一段时间,针对实际源代码中的内联元素存储数据的想法是不符合语义的”我不认为这是真的。HTML 源代码是存储网页数据的自然场所。HTML 定义结构并保存数据。
2021-03-16 23:40:21
这是另一个很好的清单,为什么onclick应该避免这种情况。
2021-03-24 23:40:21
但是还有什么地方可以存储 HTML 元素的元数据呢?什么是替代方案?
2021-03-26 23:40:21
好的,好的,编辑掉了。我不反对你的观点,我相信我也有一个,虽然,虽然很难争论。
2021-03-30 23:40:21

除了接受的答案中表达的语义和其他意见之外,所有内联脚本都被认为是一个漏洞和高安全风险。任何希望在现代浏览器上运行的网站都应该通过元属性或标头设置“内容安全策略”(CSP)属性。

这样做与所有内联脚本和样式不兼容,除非明确允许这些作为排除项。虽然 CSP 的目标主要是防止持久性跨站点脚本 (xss) 威胁,其中内联脚本和样式是 xss 的向量,但它目前不是浏览器中的默认行为,但将来可能会发生变化。

冒着重复自己的风险,您指出 onclick 是一个内联事件处理程序是语义,或没有区别的区别。“处理程序”是脚本,ergo 内联脚本。“最高投票”只是由于偏见而最高,所以对开发人员有极大的偏见,而不是安全专业人员。如果在 SO 上有更多像我这样的人,就会有更多具有安全意识的人投票。投票较少并不会导致答案错误,并且除了 SO 仅允许 1 个接受/正确的答案,但您没有经验考虑问题实际上有 1 个正确答案。
2021-03-26 23:40:21
我想你的意思是在 HTML 中根本没有 javascript。但是由于您使用术语内联 javascript,我会注意到,根据这里的最高投票答案 stackoverflow.com/questions/19618571/what-is-inline-javascript 内联 javascript 只是脚本标签之间的内容......它不是什么在例如一个 onclick 中,那将是一个内联事件处理程序。
2021-03-29 23:40:21

以@Mitya 答案为基础。

在大多数现代 JS 库中ReactVue等。内联事件处理程序被认为是惯用的,但@Mitya 提到的大部分限制都消失了。作为案例研究,我们将查看Vuejs并将其与上面列出的点进行比较:

  1. 您可以拥有多个事件处理程序,请看这里
  2. 事件值(处理程序)例如onclick不是纯字符串而是 js 表达式看这里
  3. 全局范围问题根本不存在(因为您的代码将被翻译成小型化,由webpack或其他工具重新打包)。

在我看来,内联事件处理程序主要提高可读性,但意见可能会有所不同。

React、Vue 和 Angular 可能看起来像是在使用“内联事件处理程序”,但它们没有使用原始问题中描述的 HTML属性他们正在使用指令,并且在幕后他们将使用addEventListener . 因此遵守最佳实践:developer.mozilla.org/en-US/docs/Learn/JavaScript/...
2021-03-25 23:40:21