代码之家  ›  专栏  ›  技术社区  ›  Treby

动态onclick函数在javascript中的动态参数分配?

  •  1
  • Treby  · 技术社区  · 16 年前

    我有这个代码:

    document.getElementById('img'+i).onclick = function(){popup_show('popup',array_msg[i]+'|||'+date('Y-m-d',strtotime(lec_date))+'-==-'+str_view_forConflict, 'AddEditSchedule;;popup_drag2;;EditSched;;'+String(array_msg_id[3])+';;view', 'popup_drag', 'popup_exit', 'screen-center', 0, 0);};
    

    …但是当我点击图像时,数据 array_msg[i] 是循环的最后一个数据,这意味着索引是循环的长度。我用IE做这个。

    请告诉我怎么做。在FF中,它工作正常,因为我使用 setAttribute .

    @博宾斯

    document.getElementById('img'+i).onclick= popup_show.bind(window, 'popup',array_msg[i]+'|||'+date('Y-m-d',strtotime(lec_date))+'-==-'+str_view_forConflict,'AddEditSchedule;;popup_drag2;;EditSched;;'+array_msg_id[3]+';;view','popup_drag', 'popup_exit', 'screen-center', 0, 0    ); 
                    if (!('bind' in Function.prototype)) {
                        Function.prototype.bind= function(owner) {
                            var that= this;
                            var args= Array.prototype.slice.call(arguments, 1);
                            return function() {
                                return that.apply(owner,
                                    args.length===0? arguments : arguments.length===0? args :
                                    args.concat(Array.prototype.slice.call(arguments, 0))
                                );
                            };
                        };
                    }
    
    5 回复  |  直到 16 年前
        1
  •  2
  •   Justin Johnson    16 年前

    特雷比,这是你答案的清理版本。您添加的其他匿名匿名函数不是必需的。

    for (var i = 0, l = array.length; i < l; i++ ) {
      document.getElementById(i + '05').onclick = (function(tmp) {
        return function() { 
          popup_show(
            "popup", 
            array_msg[tmp] + '|||' + date('Y-m-d', strtotime(lec_date)) + '-==-' + str_view_forConflict, 
            "AddEditSchedule;;popup_drag2;;EditSched;;" + String(array_msg_id[3]) + ";;view", 
            "popup_drag", "popup_exit", "screen-center", 0, 0
          );
        };
      })(i);
    }
    

    编辑以修复关闭问题

        2
  •  2
  •   Community Mohan Dere    9 年前

    你碰到了循环变量闭合问题。在带有闭包的C风格语言中,这是一个非常常见的gotcha,例如javascript和python。见接受的答案 this question 对于涉及在第二个闭包中绑定循环变量的解决方案。

    稍微少一点嵌套的解决方案是使用 function.bind() :

    for (var i= 0; i<something.length; i++) {
        document.getElementById('img'+i).onclick= popup_show.bind(window, 'popup',
            array_msg[i]+'|||'+date('Y-m-d',strtotime(lec_date))+'-==-'+str_view_forConflict,
            'AddEditSchedule;;popup_drag2;;EditSched;;'+array_msg_id[3]+';;view',
            'popup_drag', 'popup_exit', 'screen-center', 0, 0
        );
    }
    

    然而,由于这种方法是一个ECMAScript第五版的功能,大多数浏览器不支持,但它需要一些帮助,请参阅 this answer 实现向后兼容。

        3
  •  2
  •   Steve Harrison    16 年前

    你需要使用 closure . 如果您提供了循环代码以及在循环中执行的代码,但是假设您有一个标准 for 循环迭代数组时,以下代码应该有效:

    for (var i = 0, l = array.length; i < l; i++)
    {
        (function(i) {
            document.getElementById("img" + i).addEventListener("click", function() {
                popup_show("popup", array_msg[i] + "|||" + date("Y-m-d", strtotime(lec_date)) + "-==-" + str_view_forConflict, "AddEditSchedule;;popup_drag2;;EditSched;;" + String(array_msg_id[3]) + ";;view", "popup_drag", "popup_exit", "screen-center", 0, 0);
            }, false);
        })(i);
    }
    

    另外,你不应该使用 setAttribute 在Firefox中。相反,使用 element.onclick 或者,最好是 element.addEventListener ,它允许您添加多个在事件触发时要调用的函数,因此这与其他代码很好地配合(如果两位代码将一个函数分配给,例如表单中的click事件 element.onclick = function() { ... ,然后第二次分配覆盖第一次“不好”)。我用过 元素.addEventListener 在上面的代码示例中。

        4
  •  1
  •   Community Mohan Dere    9 年前

    关闭。您需要使用JavaScript闭包。看看是否有答案 this question 帮助。

        5
  •  -1
  •   Community Mohan Dere    9 年前

    工作答案:

    var closures = [];
    for (var i = 0; i < array.length; i++){
      closures[i] = (function(tmp) {
            return function() {
            document.getElementById(tmp + '05').onclick = function(){popup_show("popup", array_msg[tmp]+'|||'+date('Y-m-d',strtotime(lec_date))+'-==-'+str_view_forConflict, "AddEditSchedule;;popup_drag2;;EditSched;;"+ String(array_msg_id[3]) +";;view", "popup_drag", "popup_exit", "screen-center", 0, 0)};
            };
    })(i);
    
      closures[i]();
    }
    

    多亏了 Steve Harrison 回答。我有个主意把它包起来