[英]Event binding on dynamically created elements and passing parameters
在尋找問題的解決方案時,我發現了類似的問題,但我認為它並不是我要找的東西。
使用jQuery的.on()可以輕松綁定動態創建的元素上的事件,但是在嘗試傳遞不同的參數以調用不同的函數時,我陷入了困境。 閱讀https://developer.mozilla.org/zh-CN/JavaScript/Guide/Closures之后,我想到了以下工作示例,但是我想知道這是最好的方法還是有更優雅的解決方案?
另外,我經常讀到,由於漏洞問題,使用eval()並不是最佳實踐,但是還有另一種構建動態函數名稱的方法嗎?
編輯:
非常感謝大家的出色回答! 答案之一被刪除了嗎? 我之所以喜歡它,是因為將參數存儲在屬性中的提示。 再次感謝大家!
事件委托的要點是,您不需要將事件綁定到每個單個元素(或多次綁定到同一元素),而只需一次綁定到公共父對象,就像這樣:
function createLinks() {
var $container = $("#container"),
links = "";
for (var i=0; i < 4; i++) {
links += '<a class="linklink" href="#">Link_' + i + '</a>';
}
$container.html(links).on( "click", ".linklink", function(){
console.log( "fn action"+$(this).index());
});
}
createLinks();
為了避免使用eval
,您可以有一個函數數組並按索引調用它們:
arrayOfFunctions[ $(this).index() ]();
如果每個動作函數實際上必須是一個不同的函數(而不是一個函數,該函數根據傳遞給它的索引而有所不同),那么我將通過在鏈接上放置一個屬性,並在您點擊時將其提取來獲取它可以在這里查看它的工作: http : //jsfiddle.net/jfriend00/gFmvG/ 。
function action0(){ console.log("fn action0"); }
function action1(){ console.log("fn action1"); }
function action2(){ console.log("fn action2"); }
function action3(){ console.log("fn action3"); }
var actions = [action0, action1, action2, action3];
function createLinks() {
var $container = $("#container"),
links = "";
for (var i=0; i < 4; i++) {
links += '<a id="link_' + i + '" href="#" data-num="' + i + '">Link_' + i + '</a>';
$container.on("click", '"#link_' + i + '"', function() {
actions[$(this).data("num")]();
});
}
$container.html(links);
}
createLinks();
如果您不必為每個操作都具有單獨的功能,則可以這樣做: http : //jsfiddle.net/jfriend00/Z8Rq6/ 。
function doAction(index) {
console.log("fn action" + index);
}
function createLinks() {
var $container = $("#container"),
links = "";
for (var i=0; i < 4; i++) {
links += '<a id="link_' + i + '" href="#" data-num="' + i + '">Link_' + i + '</a>';
$container.on("click", '"#link_' + i + '"', function() {
doAction($(this).data("num"));
});
}
$container.html(links);
}
createLinks();
也可以通過執行閉包來鎖定索引值來完成此操作,但是我發現語法的可讀性較差(花費太多的腦力來讀取代碼並知道它在做什么),因此我更喜歡這種使用屬性的方式。
看來您的原始問題是您想調用一個函數,該函數的名稱將由傳入的參數確定。這些函數在作用域中是否都是全局變量? 如果是這樣,我會這樣做:
function helpCallback(index) {
return function() {
window['action' + index]();
}
}
這具有額外的優勢,如果您想將參數傳遞給actionX,則可以通過以下修改在索引之后傳遞這些參數來實現。
function helpCallback(index) {
var args = arguments;
return function() {
window['action' + index].apply(null, [].slice.call(args, 1));
}
}
因此helpCallback(1, "foo");
將返回一個調用action1('foo')
的函數
將您的函數放在一個對象中
var myFuncs = {
action0:function(){ console.log("fn action0"); },
action1:function(){ console.log("fn action1"); },
action2:function(){ console.log("fn action2"); },
action3:function(){ console.log("fn action3"); }
};
var funcNumber = "3";
for (var i=0; i < 4; i++)
{
links += '<a id="link_' + i + '" href="#">Link_' + i + '</a>';
(function(myI)
{
$container.on("click", '"#link_' + i + '"', function()
{
myfuncs["action"+funcNumber](mI);
});
})(i);
}
當然,如果它們是在全球范圍內制造的,您也可以
for (var i=0; i < 4; i++)
{
links += '<a id="link_' + i + '" href="#">Link_' + i + '</a>';
(function(myI)
{
$container.on("click", '"#link_' + i + '"', function()
{
window["action"+funcNumber](mI);
});
})(i);
}
我個人不會創建ID,然后再引用它們。 為什么不在與您創建的實際元素的綁定中使用閉包。
例如,您可以執行以下操作
function createLinks() {
var $container = $("#container");
for (var i=0; i < 4; i++) {
var link = $('<a href="#link' + i + '">Link_' + i + '</a>');
$container.append(link);
(function(){
var index = i;
link.click(function(){
alert("Do my thing " + index);
});
})();
}
}
createLinks();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.