深入學習jquery原始碼之append()和prepend()
深入學習jquery原始碼之append()和prepend()
append(content|fn)
概述
向每個匹配的元素內部追加內容。
這個操作與對指定的元素執行appendChild方法,將它們新增到文件中的情況類似。
引數
content String, Element, jQuery
要追加到目標中的內容
function(index, html) Function
返回一個HTML字串,用於追加到每一個匹配元素的裡邊。接受兩個引數,index引數為物件在這個集合中的索引值,html引數為這個物件原先的html值。
向所有段落中追加一些HTML標記。
<p>I would like to say: </p>
$("p").append("<b>Hello</b>");
[ <p>I would like to say: <b>Hello</b></p> ]
appendTo(content)
概述
把所有匹配的元素追加到另一個指定的元素元素集合中。
實際上,使用這個方法是顛倒了常規的$(A).append(B)的操作,即不是把B追加到A中,而是把A追加到B中。
在jQuery 1.3.2中,appendTo, prependTo, insertBefore, insertAfter, 和 replaceAll這個幾個方法成為一個破壞性操作,返回值是所有被追加的內容,而不僅僅是先前所選中的元素。所以,要選擇先前選中的元素,需要使用end()方法,參見例二。
引數
content String
用於被追加的內容
把所有段落追加到ID值為foo的元素中。
<p>I would like to say: </p>
<div></div><div></div>
$("p").appendTo("div");
<div><p>I would like to say: </p></div> <div><p>I would like to say: </p></div>
新建段落追加div中並加上一個class
<div></div><div></div>
$("<p/>")
.appendTo("div")
.addClass("test")
.end()
.addClass("test2");
<div><p class="test test2"></p></div>
<div><p class="test"></p></div>
prepend(content)
概述
向每個匹配的元素內部前置內容。
這是向所有匹配元素內部的開始處插入內容的最佳方式。
引數
content String, Element, jQuery
要插入到目標元素內部前端的內容
function(index, html) Function
返回一個HTML字串,用於追加到每一個匹配元素的裡邊。接受兩個引數,index引數為物件在這個集合中的索引值,html引數為這個物件原先的html值。
向所有段落中前置一些HTML標記程式碼。
<p>I would like to say: </p>
$("p").prepend("<b>Hello</b>");
[ <p><b>Hello</b>I would like to say: </p> ]
將一個DOM元素前置入所有段落
<p>I would like to say: </p>
<p>I would like to say: </p>
<b class="foo">Hello</b>
<b class="foo">Good Bye</b>
$("p").prepend( $(".foo")[0] );
<p><b class="foo">Hello</b>I would like to say: </p>
<p><b class="foo">Hello</b>I would like to say: </p>
<b class="foo">Good Bye</b>
向所有段落中前置一個jQuery物件(類似於一個DOM元素陣列)。
<p>I would like to say: </p><b>Hello</b>
$("p").prepend( $("b") );
<p><b>Hello</b>I would like to say: </p>
prependTo(content)
概述
把所有匹配的元素前置到另一個、指定的元素元素集合中。
實際上,使用這個方法是顛倒了常規的$(A).prepend(B)的操作,即不是把B前置到A中,而是把A前置到B中。
在jQuery 1.3.2中,appendTo, prependTo, insertBefore, insertAfter, 和 replaceAll這個幾個方法成為一個破壞性操作,要選擇先前選中的元素,需要使用end()方法,參見 appendTo 方法的例二。
引數
content String
用於匹配元素的jQuery表示式
把所有段落追加到ID值為foo的元素中。
<p>I would like to say: </p><div id="foo"></div>
$("p").prependTo("#foo");
<div id="foo"><p>I would like to say: </p></div>
jquery原始碼
jQuery.each({
appendTo: "append",
prependTo: "prepend"
}, function (name, original) {
jQuery.fn[name] = function (selector) {
var elems,
i = 0,
ret = [],
insert = jQuery(selector),
last = insert.length - 1;
for (; i <= last; i++) {
elems = i === last ? this : this.clone(true);
jQuery(insert[i])[original](elems);
// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
push.apply(ret, elems.get());
}
return this.pushStack(ret);
};
});
jQuery.fn.extend({
append: function () {
return this.domManip(arguments, function (elem) {
if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
var target = manipulationTarget(this, elem);
target.appendChild(elem);
}
});
},
prepend: function () {
return this.domManip(arguments, function (elem) {
if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
var target = manipulationTarget(this, elem);
target.insertBefore(elem, target.firstChild);
}
});
},
domManip: function (args, callback) {
// Flatten any nested arrays
args = concat.apply([], args);
var first, node, hasScripts,
scripts, doc, fragment,
i = 0,
l = this.length,
set = this,
iNoClone = l - 1,
value = args[0],
isFunction = jQuery.isFunction(value);
// We can't cloneNode fragments that contain checked, in WebKit
if (isFunction ||
(l > 1 && typeof value === "string" &&
!support.checkClone && rchecked.test(value))) {
return this.each(function (index) {
var self = set.eq(index);
if (isFunction) {
args[0] = value.call(this, index, self.html());
}
self.domManip(args, callback);
});
}
if (l) {
fragment = jQuery.buildFragment(args, this[0].ownerDocument, false, this);
first = fragment.firstChild;
if (fragment.childNodes.length === 1) {
fragment = first;
}
if (first) {
scripts = jQuery.map(getAll(fragment, "script"), disableScript);
hasScripts = scripts.length;
// Use the original fragment for the last item instead of the first because it can end up
// being emptied incorrectly in certain situations (#8070).
for (; i < l; i++) {
node = fragment;
if (i !== iNoClone) {
node = jQuery.clone(node, true, true);
// Keep references to cloned scripts for later restoration
if (hasScripts) {
jQuery.merge(scripts, getAll(node, "script"));
}
}
callback.call(this[i], node, i);
}
if (hasScripts) {
doc = scripts[scripts.length - 1].ownerDocument;
// Reenable scripts
jQuery.map(scripts, restoreScript);
// Evaluate executable scripts on first document insertion
for (i = 0; i < hasScripts; i++) {
node = scripts[i];
if (rscriptType.test(node.type || "") &&
!jQuery._data(node, "globalEval") && jQuery.contains(doc, node)) {
if (node.src) {
// Optional AJAX dependency, but won't run scripts if not present
if (jQuery._evalUrl) {
jQuery._evalUrl(node.src);
}
} else {
jQuery.globalEval((node.text || node.textContent || node.innerHTML || "").replace(rcleanScript, ""));
}
}
}
}
// Fix #11809: Avoid leaking memory
fragment = first = null;
}
}
return this;
}
});