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

时间:2020-03-05 18:44:53  来源:igfitidea点击:

我看到了两种在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(或者另一个著名的库)进行艰苦的工作的巨大好处是(很大程度上)照顾到了跨浏览器的支持,这使生活变得更加轻松