关于html:动态onclick函数赋值与JavaScript中的动态参数?

Dynamic onclick function assignment with dynamic parameters in JavaScript?

我有这个代码:

1
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

@bobince

1
2
3
4
5
6
7
8
9
10
11
12
13
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))
                            );
                        };
                    };
                }

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

1
2
3
4
5
6
7
8
9
10
11
12
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);
}

编辑修复关闭问题


你遇到了循环变量闭包问题。这是带有闭包的C风格语言中非常常见的问题,例如JavaScript和Python。有关在第二个闭包中绑定循环变量的解决方案,请参阅此问题的已接受答案。

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

1
2
3
4
5
6
7
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第五版功能,但它需要一些帮助? - ?请参阅本答案的底部以获得向后兼容的实现。


你需要使用一个闭包。如果你提供了循环代码以及在循环中执行的代码会有所帮助,但假设你有一个标准的for循环迭代数组,下面的代码应该可以工作:

1
2
3
4
5
6
7
8
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);
}

此外,您不应该在Firefox中使用setAttribute。相反,使用element.onclick或者,最好是element.addEventListener,它允许您添加多个函数,以便在事件触发时调用,因此这与其他代码很好地匹配(如果两位代码将一个函数分配给,例如,单击element.onclick = function() { ...形式的事件,然后第二个赋值覆盖第一个 - 不好的)。我在上面的代码示例中使用了element.addEventListener


闭包。您需要使用JavaScript闭包。看看这个问题的答案是否有帮助。


工作答案:

1
2
3
4
5
6
7
8
9
10
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]();
}

感谢史蒂夫哈里森答案。我知道要把它包裹起来