扩展原生appendChild方法

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 = '<div><script>wrap.append("deepScript");</script></div>',
    newScriptNode = document.createElement('script'),
    outerScript = '<script src="./outerScript.js"></script>';

newScriptNode.textContent = 'wrap.append("newScriptNode");';

wrap.appendChildPlus(deepScript, newScriptNode, outerScript, '<div>nihao</div>');

// outerScript.js
wrap.append('outerScript');
<!--extend.html-->
<!--运行前-->
<div class="js-wrap"></div>
<script src="../appendChildPlus.js"></script>
<script src="./extend.js"></script>

<!--运行后-->
<div class="js-wrap">
    <div><script>wrap.append("deepScript");</script></div>
    <script>wrap.append("newScriptNode");</script>
    <script src="./outerScript.js"></script>
    <div>nihao</div>
    deepScript
    newScriptNode
    outerScript
</div>
<script src="../appendChildPlus.js"></script>
<script src="./extend.js"></script>

更多

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
原生JS中的el-table是指element-ui库中的表格组件。它可以通过使用element-ui提供的API来创建和操作表格。在原生JS中,可以使用以下代码来创建el-table组件: ```javascript // 创建el-table组件 var table = document.createElement('el-table'); table.setAttribute('v-loading', 'dataListLoading'); table.setAttribute(':data', 'dataList'); table.setAttribute('border', ''); table.setAttribute('align', 'center'); // 创建el-table-column组件 var column = document.createElement('el-table-column'); column.setAttribute(':label', 'item.propName'); column.setAttribute(':property', 'item.propItem'); column.setAttribute('v-for', 'item in tableColumnList'); column.setAttribute(':key', 'item.prop'); column.setAttribute('align', 'center'); // 创建template和span元素 var template = document.createElement('template'); var span = document.createElement('span'); span.textContent = '{{scope.row\[scope.column.property\]}}'; // 将span元素添加到template中 template.appendChild(span); // 将template元素添加到el-table-column组件中 column.appendChild(template); // 将el-table-column组件添加到el-table组件中 table.appendChild(column); // 将el-table组件添加到页面中的某个元素中 var container = document.getElementById('container'); container.appendChild(table); ``` 以上代码是通过原生JS动态创建el-table组件的示例。你可以根据自己的需求进行修改和扩展。 #### 引用[.reference_title] - *1* [el-table 动态表格实现+原生表格实现代码](https://blog.csdn.net/weixin_50748620/article/details/123419248)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [el-table表格——获取单击的是第几行和第几列 & 表格排序之el-table与sort-change、el-table-column与sort-...](https://blog.csdn.net/weixin_44867717/article/details/125618132)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值