使用 JSLint 上的“Good Parts”默认值,不允许使用 HTML 事件处理程序(例如 onclick)。
这背后的逻辑是什么?他们有什么不好的地方应该避免?
使用 JSLint 上的“Good Parts”默认值,不允许使用 HTML 事件处理程序(例如 onclick)。
这背后的逻辑是什么?他们有什么不好的地方应该避免?
使用 JSLint 上的“Good Parts”默认值,不允许使用 HTML 事件处理程序(例如 onclick)。
标记了在实际标记中使用事件处理程序,是的:
<div onclick="...">
这通常被认为是不好的做法。将脚本行为混合到标记中很难阅读和管理;更容易将所有脚本放在一个实际的脚本中,因此您不必深入研究标记来查找正在调用的脚本钩子。
此外,通过将您的脚本代码放在需要 HTML 编码的上下文中,您正在添加一个额外的转义层。你最终会说一些讨厌的话,比如:
<div onclick="if (a<b) this.innerHTML= "I said \"Hello &amp; welcome!\""">
自然地,很难正确编码,并且如果您正在处理动态值,则错误的编码组合会给您带来脚本注入(XSS)问题。
在独立脚本中也是如此:
somediv.onclick= function() {
if (a<b)
this.innerHTML= "I said \"Hello & welcome!\"";
};
是一个更清晰的逃逸级别。
JSLint 不会抱怨这种用法。虽然有些人会争辩说使用侦听器会更好,因为您可以向一个事件添加多个侦听器,但这更像是一种重量级的解决方案,因为您必须解决 IE<9attachEvent
而不是IE addEventListener
,并且可能为不支持的旧浏览器提供一些东西。
这个逻辑最好用“关注点分离”这句话来概括,这是软件工程的一个共同原则。在这种情况下,在 HTML 中具有内联事件处理程序会将行为问题(事件处理程序)带入您的表示问题 (HTML)。有关一些古老的建议,请参阅Unobtrusive DHTML, and the power of unordered lists。其他好的来源是A List Apart,当然还有Wikipedia。
我认为原因是这样的:
当您使用默认事件处理程序时,只能有一个注册函数。
可能已经定义了一个(通过onclick
属性),当您在 JS 代码中重新定义它时,原始处理程序会丢失,可能会破坏功能。如果您采用“添加事件处理程序”路线(例如通过 jQuery 的bind()
),则不会发生这种情况。
对于您完全控制的小型 Web 应用程序,这可能没问题。如果您正在编写的 JS 代码是某种插件/库,那么这种行为将变得不可接受。
他们没有任何问题。但是,您只能通过该方法附加一个侦听器(而不是使用addEventListener
/ attachEvent
,它允许多个侦听器)。但是,对于简单的应用程序,这可能不是问题。
另一个问题是,如果您在 HTML 中使用事件处理程序属性,您会将内容与行为混合在一起。这并不理想,不引人注目的 JavaScript 人群会因为这样做而对你嗤之以鼻,但同样,实现这种分离并不是唯一的考虑因素,对于一个非常简单的应用程序,我更喜欢这种方法,因为它很简单。事件处理程序属性还有一个其他机制不具备的特性,即 JavaScript 行为在元素被渲染后立即可用,而不是在文档加载后(通常会分配事件处理程序的时间)。