使用OnClick =或脚本附加事件侦听器

时间:2013-08-29 09:23:01

标签: javascript jquery

虽然已经有人问过,但我想解决正确的jQuery编程问题。

方法#1:

<script>
     function DoClickAction() {
          // Some work
          return false;
     }
</script>

<a href="#" id="ActionButton" onclick="DoClickAction();">Do some work</a>

VS

方法#2:

<script>
     $(function() {
          $("#ActionButton").on("click", DoClickAction);
     }

     function DoClickAction() {
          // Some work
          return false;
     }
</script>

<a href="#" id="ActionButton">Do some work</a>

我正与同事讨论这个问题,我的意见是,这两种方法都有足够的利弊,不能说“这是正确的方法”,但如果我必须选择我倾向于更喜欢方法#1,这就是原因:

方法#1专业人士:

  • 在调试别人代码时,您可以轻松地跟踪当有人按下链接时执行的jQuery代码。
  • 当您动态加载(AJAX调用)内容时,它将始终有效,无需重新绑定您的jQuery事件。

方法#2专业人士:

  • 它将生成较少的HTML代码供浏览器下载,因为脚本文件将被缓存并且不需要onclick属性。虽然此示例使用了更多代码。
  • 您可以使用相同的属性轻松地重复使用代码,尽管使用带有1功能的onclick是一回事。

您对此有何看法?

2 个答案:

答案 0 :(得分:4)

不要列出任何一种方法的专家,而是让我关注方法1的概念:

  • 更改功能名称==更改整个标记
  • 所有事件处理程序都位于全局范围内。因此,使用闭包可能会有点痛苦。
  • 动态添加新元素(通过JS或通过ajax响应)意味着你要么必须解析标记并逐个添加属性,要么你必须发送包含基本上JS函数调用的标记。不安全,不是 clean
  • 每个属性都是一个新的侦听器。您拥有的属性越多,事件循环就越重
  • 混合使用JS和HTML并不是一种好习惯。将其视为关注点分离。标记用于为客户端提供UI。 JS的工作(在浏览器中)是为了增强用户体验。他们必须一起工作,但有不同的任务。因此,它们应被视为单独的实体。

就第二种方法而言,我能想到的唯一“缺点”是:

  • 您的代码稍微难以理解,但如果有人无法弄清楚事件监听器是什么,他就不应该使用您的代码,IMO。
  • 调试可以更难,旧浏览器可能会泄漏(jQ确实包含大量与X浏览器相关的代码,所以它不适用于此。当你编写vanillaJS时它会这样做)

除此之外,method2还有另一个 major 专业版,你没有列出: delegation 。起初,代表团看起来很难,但It's easy,jQuery的$.delegate使得更容易,仍然使用$.on with a selector委托事件。
基本上,委派允许您使用单个侦听器处理整个页面或页面的一部分的所有事件,例如click。这与将事件绑定到每个元素相反。因此:事件循环上的1个监听器与数十/数百。很明显,这是一种更高效的做事方式。

假设您在页面上有一个导航div,如下所示:

<div id='nav'>
    <ul>
        <li id='nav-home'>Some pseudo-link</li>
        <li id='nav-page1'>Another</li>
    </ul>
</div>

您想要点击用户,点击其中一个<li>标签。您列出的第一种方法可以解决问题:<li id='nav-home' onclick='clickNav(event, this)'>。我正在传递事件对象 this(一个DOM引用)以访问授权我访问的所有内容。
使用委托,我可以这样做:

//jQ
$('#nav').on('click','li',function(e)
{
    $.ajax({//you know the gist
        url: 'ajax/' + $(this).id().replace('nav-',''),
        success: function(){}
    });
});
//vanillaJS:
document.getElementById('nav').addEventListener('click',function(e)
{
    e = e || window.event;
    var target = e.target || e.srcElement;
    if (e.tagName.toLowerCase() === 'li')
    {
        //perform ajax call
    }
},false);

答案 1 :(得分:1)

我自己非常偏爱#2,因为它提供了JavaScript和HTML的清晰分离。浏览器插件可以完全否定HTML中没有按钮操作的负面影响。

此外,正如您已经说过的,有时我想将onclick事件附加到表的每一行,并且在每行上设置元素的OnClick属性比简单地附加单击更浪费在其他地方用一行代码处理每个代码。