Capture the event after a section element has finished loading
You can use a MutationObserver
to detect when nodes are added to .k-content
, clone them using jQuery, and append them after .Placeafterthis
(demo):
var kContent = $('.k-content'); // the original container in which the items will be placedvar $Placeafterthis = $('.Placeafterthis'); // the cloned elements target marker placeholderfunction mutationHandler(mutation) { // the mutation handler will deal with the addition of new nodes to the original container var addedNodes = mutation.addedNodes; if (!addedNodes.length) { // if no added nodes return return; } $.each(addedNodes, function () { // iterate the add nodes var $element = $(this); if (!$element.hasClass('rbs-section')) { // if the node doesn't have the right class continue to the next one return true; } var $prevSections = $Placeafterthis.find('~ .rbs-section'); // find if there are already sections append to the target var $target = $prevSections.length === 0 ? $Placeafterthis : $prevSections.last(); // if there are sections take the last, if not use the marker /** note that using .clone(true) will also clone all jQuery event handlers and data from the original element. If you don't need this behavior, just use .clone() **/ $target.after($element.clone(true)); // append after the target });}var observer = new MutationObserver(function (mutations) { // create a new mutation observer mutations.forEach(mutationHandler);});var config = { // config should include only childList because we just want added nodes childList: true};observer.observe(kContent.get(0), config); // watch the original container with the observer
Try utilizing $.get()
, appending response to .k-content
, filtering id
of selected section
element at response to clone , add character to id
to prevent duplicate id
's in DOM
, insert after .Placeafterthis
; define getSections
set with jQuery promise object as this
, recursively call getSections
to return Array.prototype.shift()
on sections
array to return $.get()
for each item at index 0
in order, else if false
returned by !!
operator on section[0]
return this.promise()
// `id`s of `section` elements to append to `.k-content` var sections = ["#id1", "#id2", "#id3"]; // selected `id` to do stuff with var selected = sections[1]; // container var container = $(".k-content"); // `complete` handler for `$.get()` requests function selectedId(html, textStatus, jqxhr) { // decode `data` : `id` sent with request var id = decodeURIComponent(this.url.split("?")[1]).split("=")[1]; // append `section` to `container` container.append($(html).filter(id)); // if `selected` appended to `container` , // and `selected` is not in `DOM` directly after `.Placeafterthis` element // clone `selected` , append after `.Placeafterthis` element if (container.find(selected).is("*") && !$(".Placeafterthis + " + selected + "-a").is("*")) { var clone = $(selected, container).clone() .attr("id", selected.slice(1) + "-a"); $(".Placeafterthis").after(clone) } } var getSections = function getSections() { var p = sections.shift(); return !!sections && $.get("http://fiddle.jshell.net/guest271314/rvt8evoy/show/" , {"id": p}, selectedId).then(getSections) }; getSections() .then(function() { console.log("complete") })
jsfiddle http://jsfiddle.net/1d6vmdpt/5/
I got the cloning code from here and modified as needed. Using the async
on the last script
tag always works for me, but use it on an external script, I just did it inline for demonstration purposes. Most importantly the script is at the closing body tag to avoid blocking. Attached an event listener on the DOMContentLoaded event, that's when the sections should be ready (unless there's iframes in the sections...). I colored all of the elements' borders for easy viewing.
UPDATE: After reading guest271314's post, it reminded me that I neglected to consider the clone's IDs. As clones they'd have identical ids as well, so I refactored it a bit and added a bit of Star Wars.
section[id^="id"] { border: 3px solid silver; width: 200px; height: 25px;}section[id^="st"] { border: 3px solid black; width: 200px; height: 25px;}.kamino-content { border: 3px dashed blue; width: 200px; height: 200px;}.Placeafterthis { border: 3px dotted orange; width: 200px; height: 75px;}
<div class="Placeafterthis"> Place After This</div><div class="kamino-content"> <section class="fett-dna" id="id1" name="jango"> .. // section content </section> <section class="fett-dna" id="id2" name="jango"> .. // section content </section> <section class="fett-dna" id="id3" name="jango"> .. // section content </section> Kamino-Content</div><script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.4.min.js"></script><!-- You should really do this: <script async src="external.js"></script> --><script async> document.addEventListener("DOMContentLoaded", cloneLab, false); function cloneLab() { var vat = $('.kamino-content'), squad = $('.fett-dna').size(), fett = vat.find('.fett-dna'); fett.each(function(idx, val) { var trooper = $(this).clone(); trooper.attr("id", "st" + (squad + idx)).attr("name", "stormtrooper"); trooper.insertAfter('.Placeafterthis'); }); }</script>