jQuery源码解析----domManip

描述:jQuery的append()函数的核心函数模拟

一、append调用

    $("#test3").click(function() {
        append(document.querySelectorAll('div')[0],"<script>alert('慕课网')" )
    })

二、模拟实现script加载

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;
    }

    //关闭脚本执行
    function disableScript(elem) {
        elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
        return elem;
    }

    //还原脚本
    function restoreScript(elem) {
        elem.removeAttribute("type");
        return elem;
    }

    function domManip(parentEles, target, callback) {
        var l = parentEles.length;
        var iNoClone = l - 1;
        var scripts;
        var hasScripts;
        if (l) {
            var fragment = buildFragment([target], parentEles[0].ownerDocument);
            var first = fragment.firstChild.firstChild
            if (first) {
                //"<script type="false/">alert('慕课网')
                //增加false标记
                scripts = disableScript(first);
                hasScripts = true
                callback.call(parentEles, scripts);
            }

            //执行脚本加载
            if(hasScripts){
                //去掉type锁定
                restoreScript(scripts);
                //开始执行脚本
                //
                // 以任意数量的一个空白字符,包括空格、制表符、换页符和换行符开始和结束
                //空白中间只能是<!开头,和>这个结尾
                //在开头和结尾中间又只能出现(?:[CDATA[|--)或(?:]]|--)这两种字符串:
                // 1) 第一种可以是[CDATA[ 或者是--
                // 2) 第二种可以是]] 或者是--
                // 目标结果就是
                // <![CDATA[]]>
                // <!---->
                // 然后就是replace把符合这样的结构的字符串(注释语句)给干掉。
                //
                var code = scripts.textContent.replace(/^s*<!(?:[CDATA[|--)|(?:]]|--)>s*$/g, "");
                eval(code)
            }

        }

    }

    function append(parentEles, target) {
        return domManip([parentEles], target, function(elem) {
            parentEles.appendChild(elem)
        });
    }
 

 总结:

  domMniap的主要工作:

  1.根据用户传入的参数,创建了多个fragment,然后通过回调函数参数传入

   2.控制script的执行过程,在创建fragment的时候不执行,最后dom操作结束后会统一执行

原文地址:https://www.cnblogs.com/abab301/p/8711404.html