在JavaScript中添加事件的最佳方法是什么?
我看到了两种在JavaScript中设置事件的主要方法:
- 像这样直接在标记内添加事件:
<a href="" onclick="doFoo()">执行foo </a>
- 像这样通过JavaScript设置它们:
<a id="bar" href=""> do bar </a>
并在<head>
部分内的<script>
部分或者外部JavaScript文件中添加事件,例如,如果我们使用prototypeJS:
Event.observe(window, 'load', function() { $('bar').observe('click', doBar); }
我认为第一种方法更易于阅读和维护(因为JavaScript操作直接绑定到链接),但不是那么干净(因为即使页面未完全加载,用户也可以单击链接,这可能会导致JavaScript错误)在某些情况下)。
第二种方法是更清洁的方法(在页面完全加载时添加操作),但是更难知道将操作链接到标记。
哪种方法最好?
一个杀手级的答案将不胜感激!
解决方案
回答
诸如YUI和jQuery之类的库提供仅在DOM准备好后(可以在window.onload之前)添加事件的方法。它们还确保我们可以添加多个事件处理程序,以便可以使用来自不同源的脚本,而不会由不同的事件处理程序相互覆盖。
因此,实际选择是:
一。如果脚本很简单并且只有一个脚本可以在页面上运行,请创建一个init函数,如下所示:
window.onload = function () { init(); } function init() { // actual function calls go here doFoo(); }
二。如果我们有许多脚本或者打算从不同来源混搭脚本,请使用库及其onDOMReady方法安全地添加事件处理程序
回答
I think the first method is easier to read and maintain
我发现相反的说法是正确的。请记住,有时一个给定的控件将绑定多个事件处理程序。
在一个中心位置声明所有事件有助于组织在站点上进行的操作。如果我们需要更改某些内容,则不必搜索调用函数的所有位置,只需在一个位置进行更改即可。当添加更多应该具有相同功能的元素时,我们不必记住将处理程序添加到它们中。相反,通常让它们声明一个类,甚至根本不更改它们就足够了,因为它们在逻辑上属于一个容器元素,所有子元素都关联到一个动作。从实际代码:
$$('#itemlist table th > a').invoke('observe', 'click', performSort);
这将事件处理程序连接到表中的所有列标题,以使表可排序。想象一下要使所有列标题分别可排序的工作。
回答
以我的经验,这有两点要点:
1)最重要的是要保持一致。只要我们坚持使用这两种方法,我都不认为这两种方法中的任何一种都较容易阅读。当在项目中同时使用这两种方法时,我只会感到困惑(甚至在同一页面上更糟),因为那样的话,我必须开始搜索调用并且不立即知道在哪里查找。
2)第二种,即Event.observe()在对多个事件执行相同或者非常相似的操作时具有优势,因为当所有这些调用都在同一位置时,这变得很明显。而且,正如Konrad指出的那样,在某些情况下,可以通过一次调用来解决此问题。
回答
我们还可以使用addEventListener(不在IE中)/ attachEvent(在IE中)。
检出:http://www.quirksmode.org/js/events_advanced.html
这些允许我们将一个函数(或者多个函数)添加到现有DOM对象上的事件。它们还具有允许稍后解除连接的优点。
通常,如果我们使用大量的javascript,则使javascript(而不是html)可读是很有用的。因此,我们可以说html中的onclick = X
很清楚,但这既缺乏代码的分离性-片段之间的另一种语法依赖性-又是我们必须同时阅读html和javascript的情况了解页面的动态行为。
回答
我认为通常首选第二种方法,因为它以与CSS分离表示和标记的方式相同的方式,将有关动作(即JavaScript)的信息与标记分开。
我同意这会使我们很难看到页面中发生的事情,但是像firebug这样的好工具将在很大程度上。如果将HTML和Javascript的混合程度保持在最低限度,我们还将发现更好的IDE支持。
随着项目的发展,这种方法真正发挥了作用,并且我们发现要将相同的javascript事件添加到许多不同页面上的一堆不同元素类型上。在那种情况下,单步添加事件变得容易得多,而不是必须搜索许多不同的HTML文件来查找调用特定函数的位置,这变得容易得多。
回答
我个人的喜好是在外部js文件中使用jQuery,因此js与html完全分开。我认为Java语言应该具有吸引力,因此内联(即第一个示例)并不是真正的最佳选择。当查看html时,使用js的唯一标志应该是脚本包含在头部。
添加(和处理)事件的示例可能是这样的
var myObject = { allLinkElements: null, init: function() { // Set all the elements we need myObject.setElements(); // Set event handlers for elements myObject.setEventHandlers(); }, clickedLink: function() { // Handle the click event alert('you clicked a link'); }, setElements: function() { // Find all <a> tags on the page myObject.allLinkElements = $('a'); // Find other elements... }, setEventHandlers: function() { // Loop through each link myObject.allLinkElements.each(function(id) { // Assign the handler for the click event $(this).click(myObject.clickedLink); }); // Assign handlers for other elements... } } // Wait for the DOM to be ready before initialising $(document).ready(myObject.init);
我认为,如果我们想使所有js井井有条,则此方法很有用,因为我们可以将特定的对象用于任务,并且所有内容都包含在内。
当然,让jQuery(或者另一个著名的库)进行艰苦的工作的巨大好处是(很大程度上)照顾到了跨浏览器的支持,这使生活变得更加轻松