为什么在HTML中使用onClick()是一个不好的做法?

我听说过很多次,在HTML中使用JavaScript事件,比如onClick() ,是一个不好的习惯,因为它不适合语义。 我想知道缺点是什么,以及如何解决下面的代码?

 <a href="#" onclick="popup('/map/', 300, 300, 'map'); return false;">link</a> 

您可能在谈论不引人注目的Javascript ,看起来像这样:

 <a href="#" id="someLink">link</a> 

与一个中央JavaScript文件中的逻辑看起来像这样:

 $('#someLink').click(function(){ popup('/map/', 300, 300, 'map'); return false; }); 

好处是

  • 行为(Javascript)与演示文稿(HTML)分离
  • 没有混合的语言
  • 您正在使用像jQuery这样的JavaScript框架,可以为您处理大多数跨浏览器问题
  • 您可以将行为添加到很多HTML元素中,而不会出现代码重复

如果你使用jQuery,那么:

HTML:

  <a id="openMap" href="/map/">link</a> 

JS:

 $(document).ready(function() { $("#openMap").click(function(){ popup('/map/', 300, 300, 'map'); return false; }); }); 

这有没有JS仍然工作的好处,或者如果用户中间点击链接。

这也意味着我可以通过再次重写来处理通用popup窗口:

HTML:

  <a class="popup" href="/map/">link</a> 

JS:

 $(document).ready(function() { $(".popup").click(function(){ popup($(this).attr("href"), 300, 300, 'map'); return false; }); }); 

这可以让你添加一个popup窗口,只要给它popup的类。

这个想法可以进一步扩展如下:

HTML:

  <a class="popup" data-width="300" data-height="300" href="/map/">link</a> 

JS:

 $(document).ready(function() { $(".popup").click(function(){ popup($(this).attr("href"), $(this).data('width'), $(this).data('height'), 'map'); return false; }); }); 

我现在可以在整个网站上使用相同的代码来播放大量的popup窗口,而无需编写大量的onclick内容! 耶为重用性!

这也意味着,如果稍后我决定popup窗口是不好的做法,(他们是!),并且我想用灯箱样式窗口replace它们,我可以改变:

 popup($(this).attr("href"), $(this).data('width'), $(this).data('height'), 'map'); 

 myAmazingModalWindow($(this).attr("href"), $(this).data('width'), $(this).data('height'), 'map'); 

我整个网站上的所有popup窗口现在都完全不同了。 我甚至可以做function检测来决定在popup窗口上做些什么,或者存储一个用户偏好来允许它们。 使用内联onclick,这需要大量的复制和粘贴工作。

这有几个原因是不好的:

  • 它混合了代码和标记
  • 这样写的代码会通过eval
  • 并在全球范围内运行

最简单的事情就是给你的<a>元素添加一个name属性,然后你可以这样做:

 document.myelement.onclick = function() { window.popup('/map/', 300, 300, 'map'); return false; }; 

尽pipe现代的最佳做法是使用id而不是名称,并使用addEventListener()而不是使用onclick因为这允许您将多个函数绑定到单个事件。

对于非常大的JavaScript应用程序,程序员正在使用更多的代码封装来避免污染全局范围。 为了使一个HTML元素中的onClick动作可用,它必须在全局范围内。

你可能已经看到这样的JS文件…

 (function(){ ...[some code] }()); 

这些是立即调用函数expression式(IIFE),其中声明的任何函数将只存在于其内部范围内。

如果你在一个IIFE中声明function doSomething(){} ,那么在你的HTML页面中doSomething()一个元素的onClick动作,你会得到一个错误。

另一方面,如果您在该IIFE中为该元素创buildeventListener,并且在侦听器检测到单击事件时调用doSomething() ,那么您会很好,因为listener和doSomething()共享了IIFE的范围。

对于less量代码的小型networking应用程序,这并不重要。 但是,如果你渴望编写大型,可维护的代码库, onclick=""是你应该避免的习惯。

有几个原因:

  1. 我发现它有助于分离标记,即HTML和客户端脚本。 例如, jQuery可以方便地以编程方式添加事件处理程序。

  2. 您提供的示例将在任何不支持JavaScript的用户代理中断开,或者已closures了JavaScript。 渐进增强的概念将鼓励一个简单的超链接到/map/为没有JavaScript的用户代理,然后为支持javascript的用户代理程序添加一个点击处理程序。

例如:

标记:

 <a id="example" href="/map/">link</a> 

使用Javascript:

 $(document).ready(function(){ $("#example").click(function(){ popup('/map/', 300, 300, 'map'); return false; }); }) 

这是一个名为“ Unobtrusive JavaScript ”的范例。 目前的“networking标准”说分开的function和演示文稿。

这不是一个“坏习惯”,只是大多数新的标准要求你使用事件监听器而不是内嵌的JavaScript。

另外,这可能只是个人的事情,但是我认为当你使用事件监听器时,阅读起来要容易得多,特别是如果你有超过1个JavaScript语句要运行。

你的问题会引发我想的讨论。 总体思路是分离行为和结构是很好的。 此外,afaik,一个内联的点击处理程序必须被eval导致“成为”一个真正的javascriptfunction。 这是相当古老的,虽然这是一个相当不稳定的说法。 啊,好吧,阅读一些关于它@ quirksmode.org