我们会认识到jQuery中一个叫做domManip的函数,这个函数的作用主要是处理DOM相关的操作,让传入的参数更加“干净”。
为什么需要用这个domManip函数呢?我们知道节点操作浏览器提供的接口无非就是那么几个:appendChild()通过把一个节点增加到当前节点的childNodes[]组,给文档树增加节点:cloneNode()复制当前节点,或者复制当前节点以及它的所有子孙节点:hasChildNodes()如果当前节点拥有子节点,则将返回true:insertBefore()给文档树插入一个节点,位置在当前节点的指定子节点之前。如果该节点已经存在,则删除之再插入到它的位置:removeChild()从文档树中删除并返回指定的子节点:replaceChild()从文档树中删除并返回指定的子节点,用另一个节点替换它。以上接口都有一个特性,传入的是一个节点元素。如果我们传递不是一个dom节点元素,如果是一个字符串,一个函数或者其他呢?所以针对所有接口的操作,jQuery会抽象出一种参数的处理方案,也就是domManip存在的意义了,针对很多类似接口的参数抽象jQuery内部有很多这样的函数了,如之前属性操作中的jQuery.access。
也就是说,我们传入的参数可能是字符串,函数,但是js原生的节点处理函数都希望是dom节点元素,所以domManip函数来保证处理传入的内容。
所以domManip应该有以下功能:
1:解析参数,字符串,函数,对象2:针对大数据引入文档碎片处理3:如果参数中包含script的处理
例外的情况:IE9之前满足几个条件
1:script设定defer属性
2: script元素必须位于有作用域元素之后,因为script被认为是无作用域的(页面中不可见)
换句话说,这样设置
div.innerHTML = "<div><script defer>alert(1)</srcript></div>" 可以执行
/*** 一个简单的流程* 用于描述文档处理的设计结构与流程* **/
//创建文档碎片function buildFragment(elems, context) { ? var fragment = context.createDocumentFragment(), nodes = [], i = 0, elem, l = elems.length; for (; i < l; i++) { elem = elems[i]; //创一个元素div做为容器 tmp = fragment.appendChild(context.createElement("div")); //放到文档碎片中 tmp.innerHTML = elem; } return fragment;}
//parentEles是父亲节点,target是要加入的dom节点,callback是要进行相应操作的函数function domManip(parentEles, target, callback) { var l = parentEles.length; ?//父亲节点的数量 var iNoClone = l - 1; ???? if (l) { var fragment = buildFragment([target], parentEles[0].ownerDocument); ??//Document文档对象 first = fragment.firstChild;
if (fragment.childNodes.length === 1) { fragment = first; }
if (first) { callback.call(parentEles, first); ?//如果有节点,就执行相应的函数操作 }} } function append(parentEles, target) { return domManip([parentEles], target, function(elem) { parentEles.appendChild(elem) });} $("button").click(function(){ append(document.getElementById(‘test‘),‘<div>通过append加入慕课网</div>‘ )})
其实在某些细节上还是感觉不太明白,不过还是第一次看肯定会有不懂的...
jQuery源码学习笔记(2)
原文地址:http://www.cnblogs.com/rimochiko/p/7622837.html