最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery .on() "append" - Stack Overflow

programmeradmin1浏览0评论

So I know about jQuery's .on() function to give dynamically added element's event handlers.

E.g I've used it this way

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

But is there a way to use this .on() function (or something else) to call a function once an object has been appended into the document? I ask this because I'm using a jquery plugin called Chosen which creates better select boxes, and it works by using the line

$(selector).chosen();

However that line doesn't work if it's used before an element is appended into the document, and for the sake of the cleanliness of my code it would be nice if I could call a function to run that line when the element has been appended, instead of adding that line after I've appended the element.

Edit: The problem isn't that I can't use .chosen() after I've appended the element. Because I can! I just want to be able to keep my code better organised by not having the $(selector).chosen() line hidden all the way at the bottom of my code unnoticed.

My code:

//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"});

As you can see, the 2nd to last line is the chosen line, but it just seems to be in an illogical place to me. I'm very OCD with my code :P

So I know about jQuery's .on() function to give dynamically added element's event handlers.

E.g I've used it this way

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

But is there a way to use this .on() function (or something else) to call a function once an object has been appended into the document? I ask this because I'm using a jquery plugin called Chosen which creates better select boxes, and it works by using the line

$(selector).chosen();

However that line doesn't work if it's used before an element is appended into the document, and for the sake of the cleanliness of my code it would be nice if I could call a function to run that line when the element has been appended, instead of adding that line after I've appended the element.

Edit: The problem isn't that I can't use .chosen() after I've appended the element. Because I can! I just want to be able to keep my code better organised by not having the $(selector).chosen() line hidden all the way at the bottom of my code unnoticed.

My code:

//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"});

As you can see, the 2nd to last line is the chosen line, but it just seems to be in an illogical place to me. I'm very OCD with my code :P

Share Improve this question edited Aug 15, 2013 at 12:49 Greg Hornby asked Aug 15, 2013 at 12:31 Greg HornbyGreg Hornby 7,8181 gold badge21 silver badges17 bronze badges 7
  • how do you append the element? – Stefan Neubert Commented Aug 15, 2013 at 12:33
  • 1 possible duplicate of Most efficient method of detecting/monitoring DOM changes? – Bergi Commented Aug 15, 2013 at 12:35
  • @Stefan I just use $(parentElement).append(childElement) – Greg Hornby Commented Aug 15, 2013 at 12:38
  • 1 Can you just check to see if it exists before initiating chosen? $(selector).length > 0 – Alexander Støver Commented Aug 15, 2013 at 12:40
  • @Alexander that could possibly work with a setInterval... – Greg Hornby Commented Aug 15, 2013 at 12:47
 |  Show 2 more ments

5 Answers 5

Reset to default 3

Maybe there's a better way, but I usually add a class like "to_replace" to newly created elements, and then use:

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

each time I changed anything.

document doesn't fire a change event. (Edit OP is delegating change)

If you cannot manually bind .chosen() after you append, then you may want to look into MutationObserver, though the browser support is fairly bleeding edge.

You can use livequery plugin https://github./brandonaaron/livequery, the best solution would be absolutely https://developer.mozilla/en-US/docs/Web/Guide/DOM/Events/Mutation_events ,but browser support is really poor.

I just found the answer I needed on another question, but it was never accepted. The answer is by Mario Bellart, Fire OnAppend event for jQuery element when it gets appended to the DOM

How I adapted his code

//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");

I did not know about .trigger() and creating custom events. Maybe I should do some more reading up.

I had the problem of add a class to an element i've created and appended, since this class have transition, css transitions doesn't work if element is not in the DOM tree, all solutions i've tried didn't work for me so i ended up with this workaround:

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

In this way the class will be added only after the element has been added in the DOM.

发布评论

评论列表(0)

  1. 暂无评论