我有一个包含部分的div:
<div class="Placeafterthis">
</div>
...
<div class="k-content">
<section class="rbs-section" id="id1" name="">
.. // section content
</section>
<section class="rbs-section" id="id2" name="">
.. // section content
</section>
<section class="rbs-section" id="id3" name="">
.. // section content
</section>
</div>
现在,基本上这些部分在DOM准备好时加载。有没有办法可以检查特定部分何时完成加载?一旦完成加载,我需要克隆该部分并将其放置在“Placeafterthis”div之后。关于如何实现这一目标的任何建议?
答案 0 :(得分:6)
您可以使用MutationObserver
检测何时使用jQuery将节点添加到.k-content
,clone,并在.Placeafterthis
之后追加它们(demo) :
var kContent = $('.k-content'); // the original container in which the items will be placed
var $Placeafterthis = $('.Placeafterthis'); // the cloned elements target marker placeholder
function 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
答案 1 :(得分:1)
我从here获得了克隆代码,并根据需要进行了修改。使用最后async
标记上的script
始终适用于我,但在外部脚本上使用它,我只是为了演示目的而内联。最重要的是,脚本位于关闭正文标记处以避免阻塞。在DOMContentLoaded事件上附加了一个事件监听器,就是这些部分应该准备好的时候(除非部分中有iframe ......)。我为所有元素的边框着色,以便于查看。
更新:在阅读guest271314的帖子后,它提醒我,我忽略了考虑克隆的ID。作为克隆,他们也有相同的ID,所以我重构了一点,并添加了一些星球大战。
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>
答案 2 :(得分:1)
尝试使用$.get()
,对.k-content
添加回复,在回复克隆时过滤所选id
元素的section
,将字符添加到id
以防止重复id
中的DOM
,.Placeafterthis
之后插入;使用jQuery promise对象将getSections
设置为this
,递归调用getSections
以返回Array.prototype.shift()
数组上的sections
以返回每个项目的$.get()
索引0
按顺序排列,如果false
运算符在!!
返回section[0]
返回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/
答案 3 :(得分:0)
如果您将脚本放在最后一部分之后:
<section class="rbs-section" id="id3" name="">
.. // section content
</section>
<script>
(function() {
var s3 = document.getElementById("id3");
...
})();
</script>
然后它将在该元素之后完全调用,其前身将出现在DOM中。