【问题标题】:jQuery .on() "append"jQuery .on() “追加”
【发布时间】:2013-08-15 12:31:34
【问题描述】:

所以我知道 jQuery 的 .on() 函数可以动态添加元素的事件处理程序。

比如我就是这样用的

$(document).on("change",Items,function(){/*Code here*/});

但是,一旦将对象附加到文档中,有没有办法使用这个 .on() 函数(或其他东西)来调用函数?我问这个是因为我使用了一个名为 Chosen 的 jquery 插件,它可以创建更好的选择框,并且它通过使用该行来工作

$(selector).chosen();

但是,如果在将元素附加到文档之前使用该行,则该行不起作用,并且为了我的代码的整洁,如果我可以在元素有时调用函数来运行该行,那就太好了已附加,而不是在我附加元素后添加该行。

编辑:问题不在于我在添加元素后无法使用 .chosen() 。因为我可以!我只是希望能够通过不让代码底部一直隐藏的 $(selector).chosen() 行而不被注意来更好地组织我的代码。

我的代码:

//Create the dropdown box for the items
var Items = document.createElement("select");
$(Items).attr( {"id":"Items"} );

$(document).on("change",Items,
    function(){
        updateHolder(true);
        $(InfoBox).trigger("chosen:updated");
        setTimeout(
            function(){
                $(Items).data('chosen').input_blur();
            }, 100
        );
    }
);

//Add items from ED.listOfItems to HTML Items dropdown box
for(var it in ED.listOfItems){
    var iKey = ED.listOfItems[it];
    var itemOption = document.createElement("option");
    if(!Array.isArray(iKey)){
        $(itemOption).val(iKey);
        $(itemOption).html(iKey.split("_")[0]);
    }
    else{
        $(itemOption).val(iKey[0]);
        $(itemOption).html(iKey[1]);

    }
    $(Items).append( itemOption );
}

/*******Set default to spawn*******/
/**/ ED.objectType = "Spawn";   /**/
/**/ ED.infoType = "";          /**/
/**/ $(Items).val("Spawn");     /**/
/**********************************/


$(MenuBar).append(Items);

$(Items).chosen({disable_search_threshold: 100});
$("#Items_chosen").css({"width":"100px","position":"absolute","left":"5px","top":"20px"});

如您所见,倒数第二行是所选行,但对我来说,它似乎处于不合逻辑的位置。我的代码非常强迫症:P

【问题讨论】:

标签: javascript jquery


【解决方案1】:

也许有更好的方法,但我通常会在新创建的元素中添加一个类似“to_replace”的类,然后使用:

$(".to_replace").each(function() {
    $(this).removeClass("to_replace").choosen();   
})

每次我改变任何东西。

【讨论】:

  • 这很有用。不完全是我想要的方式,但似乎我只需要在我附加它之后坚持在我的代码中应用 .chosen() 。虽然这个小技巧以后可能会救我!
【解决方案2】:

document 不会触发 change 事件。编辑 OP 正在委派change

如果您在append 之后无法手动绑定.chosen(),那么您可能需要查看MutationObserver,尽管浏览器支持相当先进。

【讨论】:

  • 是的,但是 Items 变量是一个 select 元素,jquery .on() 方法会在每次更改时将该函数绑定到该元素。这就是它的工作原理。此外,MutationObserver 看起来很有趣,但是当这只是为了纯粹美观的代码时只会让我的代码更混乱:P 不过仍然有用,谢谢!
  • 是的,对不起,我没有注意到事件委托是我的错误,尽管要正确委托它,您应该使用选择器字符串,而不是元素引用。
【解决方案3】:

你可以使用livequery插件https://github.com/brandonaaron/livequery,最好的解决方案绝对是https://developer.mozilla.org/en-US/docs/Web/Guide/DOM/Events/Mutation_events,但是浏览器支持真的很差。

【讨论】:

    【解决方案4】:

    我刚刚在另一个问题上找到了我需要的答案,但从未被接受。答案是马里奥·贝拉特,Fire OnAppend event for jQuery element when it gets appended to the DOM

    我如何修改他的代码

    //Create the dropdown box for the items
    var Items = document.createElement("select");
    $(Items).attr( {"id":"Items"} );
    
    $(document).on("append", Items,
        function(){
            $(Items).chosen({disable_search_threshold: 100});
            $("#Items_chosen").css({"width":"100px","position":"absolute","left":"5px","top":"20px"});
        }
    );
    
    $(document).on("change",Items,
        function(){
            updateHolder(true);
            $(InfoBox).trigger("chosen:updated");
            setTimeout(
                function(){
                    $(Items).data('chosen').input_blur();
                }, 100
            );
        }
    );
    
    //Add items from ED.listOfItems to HTML Items dropdown box
    for(var it in ED.listOfItems){
        var iKey = ED.listOfItems[it];
        var itemOption = document.createElement("option");
        if(!Array.isArray(iKey)){
            $(itemOption).val(iKey);
            $(itemOption).html(iKey.split("_")[0]);
        }
        else{
            $(itemOption).val(iKey[0]);
            $(itemOption).html(iKey[1]);
    
        }
        $(Items).append( itemOption );
    }
    
    /*******Set default to spawn*******/
    /**/ ED.objectType = "Spawn";   /**/
    /**/ ED.infoType = "";          /**/
    /**/ $(Items).val("Spawn");     /**/
    /**********************************/
    
    $(MenuBar).append(Items).trigger("append");
    

    我不知道 .trigger() 和创建自定义事件。也许我应该多读一些。

    【讨论】:

      【解决方案5】:

      我遇到了向我创建和附加的元素添加类的问题,因为这个类有转换,如果元素不在 DOM 树中,css 转换不起作用,我尝试过的所有解决方案都没有'不适合我,所以我最终得到了这个解决方法:

        elementParent.append(elementToAdd);
        setTimeout(() => {
          $(elementToAdd).addClass("show");
        }, 0);
      

      这样,只有在 DOM 中添加了元素后,才会添加该类。

      【讨论】:

        猜你喜欢
        • 2013-04-26
        • 2013-10-17
        • 2012-05-25
        • 2011-06-09
        • 2014-06-07
        • 2016-03-29
        • 2013-05-21
        • 2011-09-20
        • 1970-01-01
        相关资源
        最近更新 更多