在JavaScript中添加事件的最佳方法是什么?

时间:2008-08-29 07:35:57

标签: javascript html events event-binding

我看到了在JavaScript中设置事件的两种主要方法:

  1. 直接在标记内添加事件,如下所示:

    <a href="" onclick="doFoo()">do foo</a>

  2. 通过JavaScript设置它们:

    <a id="bar" href="">do bar</a>

  3. 并在<script>部分的<head>部分或外部JavaScript文件中添加一个事件,如果您使用的是 prototypeJS

    Event.observe(window, 'load', function() {
        $('bar').observe('click', doBar);
    }
    

    我认为第一种方法更容易阅读和维护(因为JavaScript操作直接绑定到链接)但它不是那么干净(因为即使页面没有完全加载,用户也可以点击链接,这可能是在某些情况下导致JavaScript错误。)

    第二种方法更清晰(在页面完全加载时添加操作)但是更难以知道某个操作是否与标记相关联。

    哪种方法最好?

    一个杀手锏将得到充分的赞赏!

6 个答案:

答案 0 :(得分:9)

  

我认为第一种方法更易于阅读和维护

我发现情况恰恰相反。请记住,有时会将多个事件处理程序绑定到给定控件。

在一个中心位置声明所有事件有助于组织网站上发生的操作。如果您需要更改某些内容而不必搜索所有调用函数的位置,则只需在一个位置进行更改即可。添加更多应该具有相同功能的元素时,您不必记住向它们添加处理程序;相反,通常让他们声明一个类,甚至根本不更改它们,因为它们逻辑上属于一个容器元素,所有子元素都连接到一个动作。从实际代码:

$$('#itemlist table th > a').invoke('observe', 'click', performSort);

这将事件处理程序连接到表中的所有列标题,以使表可排序。想象一下,努力使所有列标题可以单独排序。

答案 1 :(得分:3)

根据我的经验,有两个要点:

1)最重要的是要保持一致。我不认为这两种方法中的任何一种都必须更容易阅读,只要你坚持下去。我只是在项目中使用这两种方法时感到困惑(或者更糟糕的是在同一页面上)因为那时我必须开始搜索调用而不是立即知道在哪里查看。

2)第二种类型,即Event.observe()在对多个事件采取相同或非常类似的动作时具有优势,因为当所有这些调用位于相同位置时,这变得显而易见。此外,正如康拉德指出的那样,在某些情况下,这可以通过一次通话来处理。

答案 2 :(得分:3)

我认为第二种方法通常是首选方法,因为它将有关操作的信息(即JavaScript)与标记分开,就像CSS将表示与标记分开一样。

我同意这使得查看页面中发生的事情变得更加困难,但像firebug这样的好工具会帮助你解决这个问题。如果您将HTML和Javascript的混合保持在最低限度,您还可以找到更好的IDE支持。

随着项目的增长,这种方法真正发挥作用,并且您发现您希望将相同的javascript事件附加到许多不同页面上的一堆不同元素类型中。在这种情况下,使用一个附加事件的速度变得容易得多,而不是必须搜索许多不同的HTML文件来查找特定函数的调用位置。

答案 3 :(得分:1)

您也可以使用addEventListener(不在IE中)/ attachEvent(在IE中)。

退房:http://www.quirksmode.org/js/events_advanced.html

这些允许您将函数(或多个函数)附加到现有DOM对象上的事件。它们还具有允许以后不连接的优点。

一般情况下,如果你使用了大量的javascript,那么使你的 javascript 可读是有用的,而不是你的html。所以你可以说html中的onclick=X非常清楚,但这是缺乏代码分离 - 片段之间的另一种语法依赖 - 以及你必须同时阅读html和用于理解页面动态行为的javascript。

答案 4 :(得分:0)

像YUI和jQuery这样的库提供了只在DOM准备好后才能添加事件的方法,这可以在window.onload之前。它们还确保您可以添加多个事件处理程序,以便您可以使用来自不同源的脚本,而不会使不同的事件处理程序相互覆盖。

所以你的实际选择是;

一。如果您的脚本很简单并且是唯一一个将在页面上运行的脚本,请创建一个类似于init的函数:

window.onload = function () {
    init();
}
function init() {
    // actual function calls go here
    doFoo();
}

两个。如果您有许多脚本或计划混搭来自不同来源的脚本,请使用库及其onDOMReady方法安全地添加您的事件处理程序

答案 5 :(得分:0)

我个人的偏好是在外部js文件中使用jQuery,因此js与html完全分开。 Javascript应该是不引人注目的,所以内联(即第一个例子)在我看来并不是真正的最佳选择。在查看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(或其他知名图书馆)努力工作的巨大好处是,(大部分)跨浏览器支持可以让生活变得更加轻松