【问题标题】:Why does JSLint restrict the use of HTML event handlers?为什么 JSLint 限制使用 HTML 事件处理程序?
【发布时间】:2023-12-01 14:51:01
【问题描述】:

使用 JSLint 上的“Good Parts”默认值,不允许使用 HTML 事件处理程序(例如 onclick)。

这背后的逻辑是什么?它们有什么不好的地方应该避免?

【问题讨论】:

    标签: javascript jslint


    【解决方案1】:

    使用 JSLint 上的“Good Parts”默认值,不允许使用 HTML 事件处理程序(例如 onclick)。

    标记实际标记中使用事件处理程序,是的:

    <div onclick="...">
    

    这通常被认为是不好的做法。将脚本行为混合到标记中很难阅读和管理;更容易将所有脚本放在一个实际的脚本中,因此您不必深入研究标记来查找正在调用的脚本钩子。

    此外,通过将您的脚本代码放在需要 HTML 编码的上下文中,您正在添加一个额外的转义层。你最终会说一些讨厌的话,比如:

    <div onclick="if (a&lt;b) this.innerHTML= &quot;I said \&quot;Hello &amp;amp; welcome!\&quot;&quot;">
    

    自然很难正确编码,如果您正在处理动态值,错误的编码组合会给您带来脚本注入 (XSS) 问题。

    在独立脚本中也是如此:

    somediv.onclick= function() {
        if (a<b)
            this.innerHTML= "I said \"Hello &amp; welcome!\"";
    };
    

    转义层次更清晰。

    JSLint 不会抱怨这种用法。虽然有些人会争辩说使用侦听器会更好,因为您可以向一个事件添加多个侦听器,但这更像是一个重量级的解决方案,因为您必须解决 IEattachEvent 而不是 addEventListener,并且可能为老年人提供一些东西两者都不支持的浏览器。

    【讨论】:

    • 我同意转义点是一个很好的转义点,但可以通过调用属性中其他地方定义的函数来减轻一些影响。另一点是,没有哪个浏览器不支持addEventListenerattachEvent 之一,值得担心。甚至 IE 5 也有 attachEvent
    • @Tim:视情况而定。今天的主流桌面浏览器都支持一个或另一个(或两者都支持!),但一旦你开始关注移动设备和其他利基市场,如老式上网本,事情就会变得更加糟糕。如果您不幸为 IEMobile
    • 很公平。我对 IE Mobile 或大多数非 WebKit 移动浏览器几乎一无所知,没有遇到过不得不使用它们的不幸。
    • 是的,可能最好保持这种方式。 IEMobile 8 之前的版本(也称为 IE 6 Mobile,因为 Windows Mobile 版本编号一直是故意的、令人困惑的迟钝)是一种让人想起噩梦 Netscape 4 的特别恐怖。
    【解决方案2】:

    这个逻辑最好用"separation of concerns"这个短语来概括,这是软件工程的一个共同原则。在这种情况下,在 HTML 中具有内联事件处理程序会将行为问题(事件处理程序)带入您的表示问题 (HTML)。有关一些古老的建议,请参阅Unobtrusive DHTML, and the power of unordered lists。其他好的来源是A List Apart,当然还有Wikipedia

    【讨论】:

      【解决方案3】:

      我认为原因是这样的:

      当您使用默认事件处理程序时,只能有一个注册函数。

      可能已经定义了一个(通过onclick 属性),当您在 JS 代码中重新定义它时,原始处理程序会丢失,可能会破坏功能。如果您采用“添加事件处理程序”路线(例如通过 jQuery 的bind()),则不会发生这种情况。

      对于您完全控制的小型网络应用程序,这可能没问题。如果您正在编写的 JS 代码是某种插件/库,那么这种行为将变得不可接受。

      【讨论】:

      • frozenPole.onlick = alert('I thzink I'm thduck...!'); 或者换句话说,你有一个有趣的错字。
      【解决方案4】:

      他们没有任何问题。但是,您只能通过该方法附加一个侦听器(而不是使用允许多个侦听器的addEventListener / attachEvent)。但是,对于简单的应用程序来说,这可能不是问题。

      另一个问题是,如果您在 HTML 中使用事件处理程序属性,则会将内容与行为混合在一起。这并不理想,不引人注目的 JavaScript 人群会因为这样做而对你嗤之以鼻,但同样,实现这种分离并不是唯一的考虑因素,对于一个非常简单的应用程序,我更喜欢这种方法,因为它很简单。事件处理程序属性还有一个其他机制不具备的特性,即 JavaScript 行为在元素被渲染后立即可用,而不是在文档加载后(通常会分配事件处理程序的时间)。

      【讨论】:

        最近更新 更多