资讯专栏INFORMATION COLUMN

扩展原生appendChild方法

kk_miles / 1118人阅读

摘要:源代码把类数组对象转换为数组。节点对象返回被替代的节点对象节点对象被替代成可以运行的如果是节点对象,则替代为可运行的节点对象递归字符串转成文档片段节点对象。返回文档片段节点对象用于扩展方法。

Node.prototype.appendChildPlus()

写于:2017-1-2 | 更新于:2017-1-3

概述

appendChild方法的缺点有两个:

不能传多个参数

参数只能是节点对象

这里给Node.prototype添加一个方法,名称为:appendChildPlus,可以认为是appendChild的加强版,特点如下:

参数可以是html字符串和节点对象

可以传多个参数

script标签字符串和新建的script节点对象插入文档以后可以正常运行

所有参数是一起插入指定节点的,而不是一个一个插入。

源代码
// appendChildPlus.js
/**
 * Created by jszhou on 2017/1/2.
 * updated by jszhou on 2017/1/3.
 */
(function () {
    /**
     * 把类数组对象转换为数组。
     */
    var toArray = Array.from || function (arg) {
            return Array.prototype.slice.call(arg);
        };

    /**
     * 判断参数是否为节点对象。
     * @param {?} arg
     * @return {boolean}
     */
    function isNode(arg) {
        return arg instanceof Node;
    }

    /**
     * 判断参数是否为script节点对象。
     * @param {?} arg
     * @return {boolean}
     */
    function isScript(arg) {
        return isNode(arg) && arg.nodeName.toLowerCase() === "script";
    }

    /**
     * 复制script节点对象,复制以后script标签的内容可以运行。
     * @param {object} script script节点对象
     * @return {object} 返回新的script节点对象
     */
    function copyScript(script) {
        var newScript = document.createElement("script");

        // 复制属性
        toArray(script.attributes).forEach(function (item) {
            newScript.setAttribute(item.nodeName, item.nodeValue);
        });

        newScript.innerHTML = script.innerHTML;

        return newScript;
    }

    /**
     * 替代script节点对象,替代以后script标签的内容可以运行。
     * @param {object} node 节点对象
     * @return {object} 返回script被替代的节点对象(script节点对象被替代成可以运行的)
     */
    function replaceAllScript(node) {
        Array.prototype.forEach.call(node.childNodes, function (item) {
            // 如果是script节点对象,则替代为可运行的script节点对象
            if(isScript(item)) {
                item.parentNode.replaceChild(copyScript(item), item);
                return;
            }
            // 递归
            if(item.childNodes.length > 0){
                replaceAllScript(item);
            }
        });

        return node;
    }

    /**
     * 字符串转成文档片段节点对象。
     * @param {String} str 字符串,可以包含script标签,转换完插入文档以后可以运行。
     * @return {Object} 返回文档片段节点对象
     */
    function strToNode(str) {
        var docFrag = document.createDocumentFragment(),
            div = document.createElement("div");

        div.innerHTML = str;

        toArray(replaceAllScript(div).childNodes).forEach(function (item) {
            docFrag.appendChild(item);
        });

        return docFrag;
    }

    /**
     * 用于扩展appendChild方法。可以传入html字符串和节点对象,可以传多个参数。
     * 如果html字符串中有script标签,插入以后可以正常运行。
     * 注意,所有参数是一起插入指定节点的,而不是一个一个插入。
     */
    Node.prototype.appendChildPlus = function () {
        var docFrag = document.createDocumentFragment();

        toArray(arguments).forEach(function (arg) {
            docFrag.appendChild(isNode(arg) ? arg : strToNode(String(arg)));
        });

        this.appendChild(docFrag);
    };
})();
示例代码
// extend.js
var wrap = document.querySelector(".js-wrap"),
    deepScript = "
", newScriptNode = document.createElement("script"), outerScript = ""; newScriptNode.textContent = "wrap.append("newScriptNode");"; wrap.appendChildPlus(deepScript, newScriptNode, outerScript, "
nihao
"); // outerScript.js wrap.append("outerScript");


nihao
deepScript newScriptNode outerScript
更多

本扩展的markdown和demo源文件在github上,点击这里查看

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/86757.html

相关文章

  • jQuery 源码系列(十五)DOM 操作

    摘要:欢迎来我的专栏查看系列文章。所以内部一个统一的做法,就是采用的方式,先对要进行操作的内部函数执行操作,然后回调执行任务。剩下的事情,就交给回调函数去处理。所以,的作用远比想象的要少。 欢迎来我的专栏查看系列文章。 可能你会觉得这个名字很奇怪这个名字很奇怪,为什么叫做 domManip,即所谓的 dom 微操作。 showImg(https://segmentfault.com/img/...

    PascalXie 评论0 收藏0
  • 自定义元素探秘及构建可复用组件最佳实践

    摘要:若自定义元素标签名称不可用则摒弃。总之,自定义元素让开发者的代码更易理解和维护,并分割为小型,可复用及可封装的模块。被称为自定义元素接口,虽然现在仍然可用,但是已经被弃用并被认为是糟糕的实现。 原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland。 这是 JavaScript 工作原理第十九章。 概述 在 前述文章中,我们介绍了 Shadow ...

    CoorChice 评论0 收藏0
  • Zepto 源码分析 3 - qsa 实现与工具函数设计

    摘要:承接第一篇末尾内容,本部分开始进入主模块,分析其设计思路与实现技巧下文代码均进行过重格式化,但代码版本同第一部分内容且入口函数不变的选择器先从第一个与原型链构造不直接相关的工具函数说起,观察的设计思路。 承接第一篇末尾内容,本部分开始进入 zepto 主模块,分析其设计思路与实现技巧(下文代码均进行过重格式化,但代码 Commit 版本同第一部分内容且入口函数不变): Zepto 的选...

    ctriptech 评论0 收藏0
  • 浏览器中的JavaScript:文档对象模型与 DOM 操作

    摘要:作为运行在浏览器中的脚本语言,它对于网页操作非常有用。在技术圈中,我们将这些指令称为操作。结论文档对象模型是浏览器创建并保留在内存中的网页的虚拟副本。资源如果你想了解更多关于文档对象模型的内容,那么还有另一篇好文章。 翻译:疯狂的技术宅原文:https://www.valentinog.com/bl... showImg(https://segmentfault.com/img/bV...

    Ilikewhite 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<