为什么在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=""
是你应该避免的习惯。
有几个原因:
-
我发现它有助于分离标记,即HTML和客户端脚本。 例如, jQuery可以方便地以编程方式添加事件处理程序。
-
您提供的示例将在任何不支持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