这篇依然是跟 ​​dom​​​ 相关的方法,侧重点是操作 ​​dom​​ 的方法。

读Zepto源码系列文章已经放到了github上 ​

源码版本

 ​

.remove()


remove: function() {
return this.each(function() {
if (this.parentNode != null)
this.parentNode.removeChild(this)
})
},


删除当前集合中的元素。

如果父节点存在时,则用父节点的 ​​removeChild​​ 方法来删掉当前的元素。

相似方法生成器

​zepto​​​ 中 ​​after​​​、 ​​prepend​​​、 ​​before​​​、 ​​append​​​、​​insertAfter​​​、 ​​insertBefore​​​、 ​​appendTo​​​ 和 ​​prependTo​​ 都是通过这个相似方法生成器生成的。

定义容器


adjacencyOperators = ['after', 'prepend', 'before', 'append']


首先,定义了一个相似操作的数组,注意数组里面只有 ​​after​​​、 ​​prepend​​​、 ​​before​​​、 ​​append​​​ 这几个方法名,后面会看到,在生成这几个方法后,​​insertAfter​​​、 ​​insertBefore​​​、 ​​appendTo​​​ 和 ​​prependTo​​ 会分别调用前面生成的几个方法。

辅助方法traverseNode


function traverseNode(node, fun) {
fun(node)
for (var i = 0, len = node.childNodes.length; i < len; i++)
traverseNode(node.childNodes[i], fun)
}


这个方法递归遍历 ​​node​​​ 的子节点,将节点交由回调函数 ​​fun​​ 处理。这个辅助方法在后面会用到。

核心源码


adjacencyOperators.forEach(function(operator, operatorIndex) {
var inside = operatorIndex % 2 //=> prepend, append

$.fn[operator] = function() {
// arguments can be nodes, arrays of nodes, Zepto objects and HTML strings
var argType, nodes = $.map(arguments, function(arg) {
var arr = []
argType = type(arg)
if (argType == "array") {
arg.forEach(function(el) {
if (el.nodeType !== undefined) return arr.push(el)
else if ($.zepto.isZ(el)) return arr = arr.concat(el.get())
arr = arr.concat(zepto.fragment(el))
})
return arr
}
return argType == "object" || arg == null ?
arg : zepto.fragment(arg)
}),
parent, copyByClone = this.length > 1
if (nodes.length < 1) return this

return this.each(function(_, target) {
parent = inside ? target : target.parentNode

// convert all methods to a "before" operation
target = operatorIndex == 0 ? target.nextSibling :
operatorIndex == 1 ? target.firstChild :
operatorIndex == 2 ? target :
null

var parentInDocument = $.contains(document.documentElement, parent)

nodes.forEach(function(node) {
if (copyByClone) node = node.cloneNode(true)
else if (!parent) return $(node).remove()

parent.insertBefore(node, target)
if (parentInDocument) traverseNode(node, function(el) {
if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
(!el.type || el.type === 'text/javascript') && !el.src) {
var target = el.ownerDocument