9

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

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

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

  2. 像这样通过 JavaScript 设置它们:

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

<script>并在该部分内的<head>部分或外部 JavaScript 文件中添加一个事件,例如,如果您使用的是原型JS :

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

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

第二种方法更简洁(在页面完全加载时添加动作),但更难知道动作是否链接到标签。

哪种方法最好?

一个杀手级的答案将不胜感激!

4

6 回答 6

9

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

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

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

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

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

于 2008-08-29T07:50:12.100 回答
4

以我的经验,这有两个要点:

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

2) 第二种,即Event.observe()当对多个事件采取相同或非常相似的动作时具有优势,因为当所有这些调用都在同一个地方时,这一点变得很明显。此外,正如 Konrad 指出的那样,在某些情况下,这可以通过一次调用来处理。

于 2008-08-29T08:10:41.037 回答
3

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

我同意这会使查看页面中发生的事情变得更加困难,但是像 firebug 这样的好工具会在这方面为您提供很多帮助。如果您将 HTML 和 Javascript 的混合保持在最低限度,您还会发现更好的 IDE 支持。

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

于 2008-08-29T09:05:59.110 回答
1

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

查看:http ://www.quirksmode.org/js/events_advanced.html

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

一般来说,如果您使用大量的 javascript,那么让您的javascript可读而不是 html 会很有用。所以你可以说onclick=X在 html 中很清楚,但这既是缺乏代码分离——片段之间的另一种语法依赖——又是你必须同时阅读 html 和 javascript 才能理解的情况页面的动态行为。

于 2008-08-29T08:29:19.120 回答
0

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

所以你的实际选择是;

一。如果您的脚本很简单,并且是唯一可以在页面上运行的脚本,请创建一个如下所示的 init 函数:

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

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

于 2008-08-29T07:41:45.473 回答
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(或其他知名库)完成这项艰巨工作的巨大好处是(很大程度上)考虑到了跨浏览器支持,这让生活变得更加轻松

于 2008-08-29T09:56:49.863 回答