• 有问题请联系QQ:2374146085
  • 有问题请联系QQ:2374146085

DOM-节点操作

2年前 (2021-09-13) 1265次浏览 已收录 0个评论 扫描二维码

网页中所有内容都是节点(标签、属性、文本、注释、空格、换行等,即万物可节点)在dom中,节点用哪个node来表示,所有节点都可通过js进行访问,所有html元素(节点)均可被增删改。

通过节点操作获取元素,它与dom提供的方法获取元素的区别:

  • 节点操作获取是利用父子兄弟节点关系获取元素
  • 逻辑性强且简单,但是兼容性稍差

节点概述

节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。

节点类型

  • 元素代表1
  • 属性代表2
  • 文本代表3

节点层级

父级节点

得到的是离元素最近的父级节点(亲爸爸)

孩子.parentNode;

子节点

childNodes(不提倡)

父亲.childNodes; //注意:返回的是所有节点,包含元素节点,文本节点,比如空格与换行等。
如果只想要获取里面的元素节点,还需要专门的处理,所以一般不提倡使用childNodes
<script>
        var ul=document.querySelector('ul');
        for(var i=0;i<ul.childNodes.length;i++){
            if(ul.childNodes[i].nodeType == 1){
                //判断ul.childNodes[i]是元素节点
                console.log(ul.childNodes[i]);
            }
        }
    </script>

children(非标准)(重点且推荐)

获取所有子元素的节点

父亲.children;

获取第一个子元素节点

var ul=document.querySelector('ul');
console.log(ul.children[0]);获取第一个子元素节点

测试:

<script>
    // 1. 获取元素
    var nav = document.querySelector('.nav');
    var lis = nav.children; // 得到4个小li
    // 2.循环注册事件
    for (var i = 0; i < lis.length; i++) {
        lis[i].onmouseover = function() {
            this.children[1].style.display = 'block';
        }
        lis[i].onmouseout = function() {
            this.children[1].style.display = 'none';
        }
    }
</script>
结果演示

兄弟元素节点(有兼容性问题)

返回当前元素的下一个兄弟元素节点

兄弟.nextElementSibling

返回当前元素的上一个兄弟元素节点

兄弟.previousElementSibling

举例:

<div>1</div>
    <span>2</span>
    <script>
        var d=document.querySelector('div');
        console.log(d.nextElementSibling);
    </script>

封装一个函数解决兼容性问题

function getNextElementSibling(element){
            var el=element;
            while(el=el.nextSibling){
                if(el.nodeType==1){
                    return el;
                }
            }
            return null;
        }

动态创建节点

创建节点

document.createElement('节点'); //动态创建元素节点

添加节点

将一个节点添加到父节点的子节点列表末尾

父亲.appendChild(节点)
<ul></ul>
    <script>
        //创建一个元素节点
        var l=document.createElement('li');
        //添加创建好的节点
        var u=document.querySelector('ul');
        u.appendChild(l);
    </script>

在指定元素节点前面添加节点

父亲.insertBefore(节点,指定元素的前面/ul.children[0])

删除节点

父亲.remonveChild(节点)

简单留言小测试

<script>
        var v=document.querySelector('input');
        var b=document.querySelectorAll('button');
        var u=document.querySelector('ul');
        //发布留言
        b[0].onclick=function(){
            var data=v.value;
            //创建元素
            var l=document.createElement('li');
            l.innerHTML=data+'<a href="javascript:;">删除</a>';
            //添加元素
            // u.appendChild(l);
            u.insertBefore(l,u.children[0]);
            //删除指定留言
            var a=document.querySelector('a');
            //给每个留言添加事件
            a.onclick=function(){
                //a的父节点就是l
                u.removeChild(a.parentNode);
            }

        }
        //依次删除留言
        // b[1].onclick=function(){
        //     var l=document.querySelector('li');
        //     u.removeChild(l);
        // }    
    </script>
结果演示

复制节点

父节点.cloneNode();括号为空或着里面是false 则代表浅拷贝,只复制标签不复制里面的内容
父节点.cloneNode(true);深拷贝 则复制标签和内容
<ul>
        <li>1</li>
        <li>2</li>
</ul>
    <script>
        var u=document.querySelector('ul');
        var ll=u.children[0].cloneNode(true);
        u.appendChild(ll);
    </script>

三种动态创建元素的区别

  • document.write()
  • element.innerHTML
  • document.createElement()

区别:

  • document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘(新页面)
  • innerHTML创建多个元素时采取数组形式拼接,效率更高,但结构稍微复杂。而采取字符串拼接时效率最低。
  • createEl.ement()创建多个元素效率稍微低一点点,但是结构更清晰。
<script>
    function fn() {
        // var d1 = +new Date();
        var array = [];
        for (var i = 0; i < 1000; i++) {
            array.push('<div></div>');
        }
        document.body.innerHTML = array.join('');
        // var d2 = +new Date();
        console.log(d2 - d1);
    }
    fn();
</script>

案例

<script>
        var datas=[
            {
            name:"渣渣龙",kemu:"js",cj:"98"
        },
            {
            name:"王学龙",kemu:"js",cj:"98"
        },
            {
            name:"王小明",kemu:"js",cj:"98"
        }
        ];
        var kuang=document.querySelector('tbody');
        for(i=0;i<datas.length;i++){//管理行 tr
            //创建行
            var tr=document.createElement('tr');
            kuang.appendChild(tr);
            //创建3个单元格
            for(j in datas[i]){ //管理列/单元格td
                var td=document.createElement('td');
                td.innerHTML=datas[i][j];//对象里第一个数组里的第一个属性名的属性值
                //往单元格里给值
                tr.appendChild(td);
            }
            //创建每一行的最后一个单元格放 删除
            var td=document.createElement('td');
            td.innerHTML='<a href="javascript:;">删除</a>';
            tr.appendChild(td);
            td.onclick=function(){
                // 删除当前a所在的行,即a的爸爸的爸爸 :a所在的单元格 单元格所在的行
                kuang.removeChild(this.parentNode);
            }
        }
        // for(var k in obj) {
        //     k 得到的是属性名
        //     obj[k] 得到是属性值
        // }
    </script>
结果演示

 


渣渣龙, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:DOM-节点操作
喜欢 (4)

您必须 登录 才能发表评论!