【问题标题】:Why is it bad practice to use links with the javascript: "protocol"?为什么使用带有 javascript:"protocol" 的链接是不好的做法?
【发布时间】:2011-01-29 14:09:09
【问题描述】:

在 1990 年代,有一种将 Javascript 代码直接放入 <a> href 属性的时尚,如下所示:

<a href="javascript:alert('Hello world!')">Press me!</a>

然后我突然停下来看它。它们都被以下内容所取代:

<a href="#" onclick="alert('Hello world!')">Press me!</a>

对于仅用于触发 Javascript 代码且没有真正的href 目标的链接,为什么鼓励使用onclick 属性而不是href 属性?

【问题讨论】:

  • 它没有被弃用.. 只是不好的做法.. 使用 onclick 属性也是如此.. 搜索 unobtrusive javascriptprogressive enhancement 以获得最佳做法..
  • @Gaby:那么“不良做法”和“已弃用”有什么区别?
  • deprecated 意味着这些功能将来很可能完全不受支持..
  • @Gaby:好吧,改正标题。
  • 我什至会考虑使用&lt;a&gt; 标签来假装它是一个页面链接的坏习惯(或实践?),而实际上它只是一个“JS 动作的触发器”。我会考虑使用 &lt;span class="js-trigger"&gt;Press me&lt;/span&gt; 并通过将相关的 javascript 代码放在单独的 JS 文件中来解耦。

标签: javascript html href


【解决方案1】:

执行上下文不同,要查看此内容,请尝试以下链接:

<a href="javascript:alert(this.tagName)">Press me!</a> <!-- result: undefined -->
<a href="#" onclick="alert(this.tagName)">Press me!</a> <!-- result: A -->

javascript: 在全局上下文中执行,而不是作为元素的方法,这通常是你想要的。在大多数情况下,您所做的事情是与您所操作的元素相关或相关的,最好在该上下文中执行它。

此外,它更简洁,尽管我根本不会使用内联脚本。查看以更简洁的方式处理这些事情的任何框架。 jQuery 中的示例:

$('a').click(function() { alert(this.tagName); });

【讨论】:

  • 只是一个简单的说明 - 当您从 href 属性调用 javascript:this 时,它是对窗口 DOM 对象的引用。
  • 感谢您解释差异,然后提出更好的方法。
  • 我觉得有趣的是,社区支持的答案的焦点 - 并且被选中 - 侧重于使用 javascript: 协议给开发人员带来的不便与其对可交付成果质量的影响相反……让我想到了电梯测试; codinghorror.com/blog/2007/09/…
  • @Richard - 这还具有位于外部和缓存文件中的优点,而不是每轮都作为页面的一部分下载...我认为出于多种原因它对质量和方便开发者。
  • @Nick Craver - 这是真的......我对措辞和内容的思考一样多;在我看来,这就像一个脚注/事后的想法。并不是说我不同意你的任何观点:)
【解决方案2】:

我认为这与用户在状态栏中看到的内容有关。通常应构建应用程序以进行故障转移,以防 javascript 未启用,但情况并非总是如此。

随着所有垃圾邮件的发生,人们变得越来越聪明,当电子邮件看起来“钓鱼”时,越来越多的人正在查看状态栏以查看链接实际会将他们带到哪里。

记得加上'return false;'到链接的末尾,这样页面就不会跳到用户的顶部(除非这是您要寻找的行为)。

【讨论】:

    【解决方案3】:

    实际上,这两种方法都已过时。相反,鼓励开发人员将所有 JavaScript 分离到一个外部 JS 文件中,以便将逻辑和代码与真正的标记分开

    这样做的原因是它创建的代码更易于维护和调试,并且还促进了 Web 标准和可访问性。可以这样想:看看你的例子,如果你在一个页面上有数百个这样的链接,并且需要使用外部 JS 引用为其他一些函数更改 alert 行为,你只需要更改一个在一个 JS 文件中绑定单个事件,而不是一遍又一遍地复制和粘贴一堆代码或进行查找和替换。

    【讨论】:

      【解决方案4】:

      简短回答:内联 Javascript 不好,因为内联 CSS 不好。

      【讨论】:

        【解决方案5】:

        使用javascript: 协议会影响可访问性,还会损害您的页面对 SEO 的友好程度。

        请注意,HTML 代表 Hypter Text something something...超文本表示其中包含链接和引用的文本,这就是锚元素 &lt;a&gt; 的用途。

        当您使用javascript:“协议”时,您正在滥用锚元素。由于您滥用&lt;a&gt; 元素,Google Bot 和 Jaws 屏幕阅读器之类的东西将难以“理解”您的页面,因为它们不太关心您的 JS,但非常关心超文本 ML,采取主播hrefs的特别说明。

        当没有启用 JavaScript 的用户访问您的页面时,它还会影响您的页面的可用性;您正在破坏这些用户的链接的预期功能和行为。它看起来像一个链接,但它不会像一个链接,因为它使用javascript 协议。

        您可能会想“但是现在有多少人禁用了 JavaScript?”但我更喜欢将这个想法表述为“我愿意因为浏览器设置中的复选框而拒绝多少潜在客户?”

        归结为href 是一个HTML 属性,因此它属于您网站的信息,而不是它的行为。 JavaScript 定义了行为,但您永远不希望它干扰数据/信息。这个想法的缩影就是外部 JavaScript 文件。不使用 onclick 作为属性,而是作为 JavaScript 文件中的事件处理程序。

        【讨论】:

        • 它是超文本标记语言。话虽这么说,我不同意你信息中的几乎所有内容,除了你的最后一段。因此,我将在另外两个 cmets 中解释原因。
        • 对于 SEO 参数,它只是协议处理。我很确定搜索引擎知道链接何时是 HTTP 链接,并且使用未知协议当然不会把它们弄乱。我很确定在我的页面上使用 mailto: 链接不会让 Google 讨厌我的页面,因为它无法关注它。
        • 此外,当链接仅用于触发脚本时,您总是会误用&lt;a&gt;,因为您必须放置一个不相关的href。在这些情况下,对于禁用 Javascript 的 UA 使用 javascript: 协议不是友好吗?假设不相关但必要的锚点是#,它只会什么都不做,而不是回到页面顶部。 (这显然是假设链接只是触发了一个 Javascript 操作。)
        • @zneak - 我知道 ML 代表什么; “某事某事”的意思是表示在我的回答范围内,HT 是重要的部分;)人们倾向于更多地关注 ML 而不是 HT。至于搜索引擎优化,你是对的; Google 不会讨厌您的网页,但也不会使其喜欢;你给它的信息它只能丢弃。何必?至于你关于更友好的说法,我也将菊花链一些cmets!
        • 我很抱歉这有点苛刻,但是使用javascript: 协议对于没有 JS 的用户实现这种友好性感觉就像 lazy 方式。我也觉得你非常喜欢使用&lt;a&gt;href 作为用户应该点击的元素,因此认为用户会得到一个指向该元素的手指光标。因此,没有 JS 的用户会将鼠标悬停在您的元素上,看到手指认为“我可以与之交互”点击它,然后什么都不会发生......
        【解决方案6】:

        此外,只要我们谈论的是弃用和语义,可能值得指出的是,“&lt;/a&gt;”并不意味着“可点击”——它的意思是“锚点”,并暗示指向另一个页面的链接。因此,使用该标签在您的应用程序中切换到不同的“视图”是有意义的,而不是执行计算。您的 href 属性中没有 URL 的事实应该表明您不应该使用锚标记。

        您也可以将点击事件操作分配给几乎任何 html 元素——也许&lt;h1&gt;&lt;img&gt;&lt;p&gt; 会更合适?无论如何,正如其他人所提到的,添加另一个属性(也许是一个“id”),javascript 可以将其用作“钩子”(document.getElementById)来获取元素并分配一个 onclick。这样,您可以将内容 (HTML) 演示 (CSS) 和交互性 (JavaScript) 分开。世界不会终结。

        【讨论】:

        • 也许&lt;span&gt;&lt;h1&gt; 更合适,因为它在语义上没有意义。但我明白了。
        【解决方案7】:

        我通常有一个名为“EnableJavascript.htm”的登录页面,上面有一条大信息,上面写着“必须启用 Javascript 才能使此功能正常工作”。然后我像这样设置我的锚标签......

        <a href="EnableJavascript.htm" onclick="funcName(); return false;">
        

        这样,锚点就有了一个合法的目的地,只要有可能,它就会被您的 Javascript 功能覆盖。这将优雅地降级。虽然,现在,我通常会先构建具有完整功能的网站,然后再决定将一些 Javascript 混入其中(所有这些都消除了对此类锚点的需求)。

        在标记中直接使用 onclick 属性是另一个话题,但我建议使用 jQuery 之类的库来使用不显眼的方法。

        【讨论】:

          【解决方案8】:

          我在新标签中打开了很多链接 - 只看到 javascript:void()。所以你惹恼了我,也惹恼了你自己(因为 Google 会看到同样的事情)。

          另一个原因(其他人也提到过)是不同的语言应该分成不同的文档。为什么?嗯,

          • 不能很好地支持混合语言 大多数 IDE 和验证器。 将 CSS 和 JS 嵌入 HTML 页面 (或其他任何事情) 几乎破坏了机会 检查嵌入语言的正确性 静态的。有时,嵌入语言也是如此。 (PHP 或 ASP 文档不是有效的 HTML。) 你不想要语法 要显示的错误或不一致 仅在运行时。
          • 另一个原因是之间有一个更清晰的分隔 你需要做的事情 指定:HTML 表示内容,CSS 表示 布局,JS通常用于更多的布局 和外观。这些不映射 一对一:你通常想申请 布局到整个类别 内容元素(因此是 CSS)以及外观和感觉 (因此是 jQuery)。他们可能会在不同的地方改变 内容元素更改的次数(实际上 内容通常是即时生成的)和 不同的人。所以把它们留在里面是有道理的 以及单独的文档。

          【讨论】:

          • 投票主要支持第一点。试图在新标签页中打开链接却只在地址栏中看到javascript:void(0) 让我抓狂
          • 我更多的是谈论只影响调用页面的 Javascript 代码。我也不喜欢看到javascript:void(0)
          【解决方案9】:

          几个原因:

          1. 错误的代码实践:
            HREF 标记用于指示存在对另一个位置的超链接引用。通过对实际上没有将用户带到任何地方的 javascript 函数使用相同的标记是不好的编程习惯。

          2. SEO 问题:
            我认为网络爬虫使用 HREF 标签来爬取整个网站并链接所有连接的部分。通过放入 javascript,我们破坏了这个功能。

          3. 打破可访问性:
            我认为一些屏幕阅读器将无法执行 javascript 并且可能不知道如何处理 javascript,而他们期望超链接。用户希望在链接悬停时在浏览器状态栏中看到一个链接,而他们会看到一个字符串,例如:“javascript:”,这可能会让他们感到困惑等。

          4. 你还在 1990 年代:
            主流建议是将您的 javascript 放在一个单独的文件中,而不是像 1990 年代那样与页面的 HTML 混合。

          HTH。

          【讨论】:

          • 我不认为 SEO 是一个有效的论据,因为他们能够很好地找出他们可以关注哪些链接,哪些不能。我会接受你关于屏幕阅读器的论点(我肯定喜欢听到计算机声音大声读出 Javascript 代码),但状态栏的事情对我来说似乎有些夸张。
          • @zneak - 也许我应该将状态栏注释从“可能会混淆他们”替换为“可能会激怒他们”。从个人经验来看,当我不想关闭当前页面时,我喜欢 Shift+单击/Ctrl+单击链接以在新窗口中打开它们,当它中断时,我想去寻找打破它的开发人员第一名:)
          • +1 错误的代码实践,没有创建 href 标签来指示 JS 代码的触发。
          【解决方案10】:

          最糟糕的问题可能是它破坏了预期的功能。
          例如,正如其他人指出的那样,在新窗口/选项卡中打开 = 死链接 = 烦人/困惑的用户。

          我总是尝试使用onclick在页面的 URL-hash 中添加一些内容以指示触发所需的功能在pageload 来检查哈希并触发函数。

          通过这种方式,您可以获得相同的点击行为、新标签页/窗口,甚至书签/发送的链接,并且如果 JS 关闭,事情也不会变得古怪。

          换句话说,像这样(非常简化):

          链接:

          onclick = "doStuff()"
          
          href = "#dostuff"
          

          对于页面:

          onLoad = if(hash="dostuff") doStuff();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-01-05
            • 2010-11-04
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多