【问题标题】:setting events programmatically以编程方式设置事件
【发布时间】:2014-02-25 23:18:14
【问题描述】:

我在我的代码中设置表格行的类名,是否可以做类似的事情来在一行上设置一个事件?这与我想做的事情一致:

for (var i = 1; i < numRows; i++) {
            var ID = table.rows[i].id;
            if (i % 2 == 0) {
                table.rows[i].className = "GridRow";
                table.rows[i].onmouseout = "GridRow";
            }
            else {
                table.rows[i].className = "GridRowAlt";
                table.rows[i].onmouseout = "GridRowAlt";
            }
        }

【问题讨论】:

    标签: javascript


    【解决方案1】:

    是的,您可以通过这种方式将函数实例分配给事件处理程序:

    table.rows[i].onmouseout = function() { ... };
    

    在循环中这样做时要小心,因为您在每个循环上都创建了一个新函数,并且该函数会关闭范围内的数据(因此对它有一个持久引用,而不是副本函数创建时的数据;更多信息请参见this other recent question)。不过不用担心,closures are not complicated 一旦您了解了它们的工作原理。

    通常,这称为“DOM0”事件处理,因为它涉及附加事件处理程序的方法,该方法是在第一个 DOM 规范之前创建的。从 DOM2 开始,有更好的方法addEventListener

    table.rows[i].addEventListener('mouseout',function() { ... }, false);
    

    它“更好”,因为您可以在同一元素的同一事件上拥有多个事件处理程序,而使用 DOM0 机制,分配一个新的事件处理程序会断开前一个事件处理程序(如果有的话)。

    遗憾的是,在 IE9 之前的 IE 上,addEventListener 不受支持,但它确实具有 非常相似 attachEvent

    table.rows[i].attachEvent('onmouseout',function() { ... });
    

    注意区别:

    • addEventListener 的事件名称没有“on”前缀
    • addEventListenerattachEvent 多一个参数,你几乎总是想设置 false

    更新

    上面所有的例子都是针对内联匿名函数的,这有点不像我,因为I don't like anonymous functions。因此,为了清楚起见,从事件的角度来看,函数就是函数。它可以是你在别处声明的命名函数,也可以是内联匿名函数,随便什么:

    // Hook up...
    table.rows[i].addEventListener('mouseout', handleRowMouseOut, false);
    
    // Nice, reusable function defined elsewhere
    function handleRowMouseOut(event) {
        // ...
    }
    

    题外话:正是这些浏览器差异导致我一般建议使用jQueryPrototypeYUIClosureany of several others 之类的库.它们为您消除差异,并提供许多方便的实用功能。

    【讨论】:

      【解决方案2】:

      table.rows[i].onmouseout = "GridRow"; 没有多大意义,table.rows[i].onmouseout = function(){alert('hello');}; 或其他一些有效的脚本应该可以工作。

      【讨论】:

      • 我很抱歉,我在 Java、JavaScript 和 C++ 之间来回穿梭,搞混了。
      • :-) 我们不是所有人。 (哦,C++,戴上和摘下那顶帽子一定很有趣,只是在内存处理上有所不同......)
      • @T.J.Crowder:没有区别。
      【解决方案3】:

      您为什么不直接使用jQuery 或其他一些JavaScript 框架?这样你的代码就变得更简单了。

      var i = 0; $('#some_table tr').each(function() { if (i % 2 == 0) { $(this).addClass('GridRow'); $(this).mouseout(function(evt) { /* your GridRow function */ }); } else { $(this).addClass('GridRowAlt'); $(this).mouseout(function(evt) { /* your GridRowAlt function */ }); } i++; })

      苏丹

      【讨论】:

      • 这对我来说看起来并不简单。 (当然,jQuery 和类似的 让很多事情变得更简单。)旁注:每次你调用$(this),有多个函数调用和一个内存需要分配。如果您发现自己在一个函数中多次写入$(this),请考虑执行一次并存储结果。哦,另外,你不需要i变量,只需要使用jQuery传递给迭代器函数的索引:api.jquery.com/each
      【解决方案4】:

      最初的问题是不要提醒“GridRow”。我确定 GridRow 是一个函数名。幸运的是,每个函数都是 window 的子函数,所以写 window["GridRow"]。

      我会添加一个众所周知的绑定事件函数,因为您经常需要它。

      var bindEvent=function(elem,evt,func){
                    if(elem.addEventListener){
                       elem.addEventListener(evt,func,false);
                    }
                    else if(elem.attachEvent){
                            elem.attachEvent('on'+evt,function(){
                                func.call(event.srcElement,event); 
                             })
                   }
      };
      

      然后:

      bindEvent(table.rows[i],"mouseout",window["GridRow"]);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-07
        • 1970-01-01
        • 2020-02-26
        • 1970-01-01
        • 2021-11-21
        • 2018-11-26
        相关资源
        最近更新 更多