簡體   English   中英

對動態創建的元素和傳遞參數進行事件綁定

[英]Event binding on dynamically created elements and passing parameters

在尋找問題的解決方案時,我發現了類似的問題,但我認為它並不是我要找的東西。

使用jQuery的.on()可以輕松綁定動態創建的元素上的事件,但是在嘗試傳遞不同的參數以調用不同的函數時,我陷入了困境。 閱讀https://developer.mozilla.org/zh-CN/JavaScript/Guide/Closures之后,我想到了以下工作示例,但是我想知道這是最好的方法還是有更優雅的解決方案?

http://jsfiddle.net/V25Zc/

另外,我經常讀到,由於漏洞問題,使用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/V25Zc/2/

如果每個動作函數實際上必須是一個不同的函數(而不是一個函數,該函數根據傳遞給它的索引而有所不同),那么我將通過在鏈接上放置一個屬性,並在您點擊時將其提取來獲取它可以在這里查看它的工作: 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM