为什么使用JavaScript:“协议”的链接是不好的做法?

在20世纪90年代,有一种将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属性?

执行上下文是不同的,看到这个,试试这些链接:

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

实际上,这两种方法都被认为是过时的。 相反鼓励开发人员将外部JS文件中的所有JavaScript分开,以便将逻辑和代码从真正的标记中分离出来

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

几个原因:

  1. 不良的代码实践:
    HREF标记是为了表明有一个超链接引用到另一个位置。 通过使用相同的标签的JavaScriptfunction,实际上并没有把用户的地方是不好的编程习惯。

  2. SEO问题:
    我认为networking爬虫使用HREF标签来爬行整个网站和链接所有连接的部分。 通过放入JavaScript,我们打破了这个function。

  3. 可达性:
    我认为一些屏幕阅读器将无法执行JavaScript&可能不知道如何处理JavaScript,而他们期望超链接。 用户希望在链接hover的浏览器状态栏中看到一个链接,同时他们将看到一个像“javascript:”这样的string,这可能会混淆他们等等。

  4. 你还在二十世纪九十年代
    主stream的build议是把你的JavaScript放在一个单独的文件中,而不是像20世纪90年代那样混合页面的HTML。

HTH。

我在新标签中打开了很多链接 – 只能看到javascript:void()。 所以你和我一样烦恼,因为Google会看到同样的事情。

另一个原因(别人也提到)是不同的语言应该被分成不同的文件。 为什么? 好,

  • 大多数IDE和validation器都不支持混合语言。 将CSS和JSembedded到HTML页面(或其他任何事情)几乎破坏了embedded式语言静态检查正确性的机会。 有时候,embedded语言也是如此。 (PHP或ASP文档不是有效的HTML。)您不希望仅在运行时显示语法错误或不一致。
  • 另一个原因是在你需要指定的东西之间有一个更清晰的分隔:内容的HTML,布局的CSS,JS通常用于更多的布局和外观。 这些不是一对一的映射:你通常要将布局应用于整个内容元素的类别 (因此CSS)和外观(也就是jQuery)。 它们可能在不同的时间被改变,以致内容元素被改变(实际上内容通常是在飞行中生成的)并且由不同的人来改变。 因此,将它们保存在单独的文档中也是有意义的。

简答:内联Javascript是不好的,因为内联CSS是坏的。

使用javascript:协议会影响可访问性,同时也会伤害你的页面。

请注意,HTML代表Hypter Text的东西…超文本表示带有链接和引用的文本,这是一个锚元素<a>的用途。

当您使用javascript: '协议'时,您正在滥用锚点元素。 由于您滥用了<a>元素,像Google Bot和Jaws Screen reader这样的东西将无法“理解”您的页面,因为他们不关心您的JS,而是关心超文本ML,锚hrefs特别注意。

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

你可能会想“但现在有多less人禁用了JavaScript?” 但我更愿意按照“只有因浏览器设置中的checkbox而愿意退出多less潜在客户?

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

最糟糕的问题可能是它打破了预期的function。
例如,正如其他人所指出的,在新窗口/ tab = dead link =恼火/困惑的用户中打开。

我总是尝试使用onclick添加一些东西到页面的URL哈希来指示所需的函数来触发, 在页面加载检查哈希和触发函数。

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

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

对于链接:

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

对于页面:

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

另外,只要我们讨论弃用和语义,可能值得指出的是,“ </a> ”并不意味着“可点击” – 这意味着“锚定”,并意味着链接到另一个页面。 因此,使用该标记切换到应用程序中的其他“视图”,但不执行计算是有意义的。 您在href属性中没有URL的事实应该是您不应该使用锚标签的一个标志。

您可以交替地将点击事件动作分配给几乎所有的HTML元素 – 也许一个<h1> ,一个<img>或一个<p>会更合适? 无论如何,正如其他人所提到的那样,添加另一个属性(也许是'id'),可以使用javascript作为“钩子”(document.getElementById)来获取元素并分配onclick。 这样你可以保持你的内容(HTML)的演示文稿(CSS)和交互性(JavaScript)分开。 世界不会结束。

我认为这与用户在状态栏中看到的内容有关。 通常情况下,应用程序应该build立故障转移的情况下JavaScript未启用,但事实并非总是如此。

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

请记得添加“返回false” 到链接的结尾,这样页面就不会跳转到用户的顶部(除非这是你正在寻找的行为)。

我通常有一个名为“EnableJavascript.htm”的登陆页面,其中有一个很大的消息,说:“必须启用JavaScript才能使用此function”。 然后我设置我的锚标签像这样…

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

这样,锚点有一个合法的目的地,只要有可能就会被Javascript的function覆盖。 这将优雅地退化。 虽然,现在一天,我通常build立具有完整function的网站,然后再决定在组合中join一些Javascript(这一切都消除了这种锚的需求)。

直接在标记中使用onclick属性是一个完整的主题,但是我会推荐一个像jQuery这样的库的不显眼的方法。