DOM(三):节点操作——获取父子兄节点(查)、添加和删除元素节点

之前要想获取元素,得先获取父亲再获取你想要的,逻辑性不强而且繁琐(利用dom提供的方法来获取)

利用节点层级关系来获取更方便,逻辑性强但是兼容性差

一、节点之间的层级

1.父节点操作

<div class="box">
        <div class="code"></div>
    </div>
    <script>
      var code=document.querySelector('.code');
     // var box=document.querySelector('.box');//以前的做法
     code.parentNode;//现在的新做法,直接获取父亲节点
    </script>

parentNode得到的是离它最近的父亲,如果它还有爷爷的话,得到的也是父亲,如果找不到返回null

2.子节点操作

 <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
    </ul>
    <script>
      var ul=document.querySelector('ul');
     // var lis=document.querySelectorAll('li');//以前的做法
     ul.childNodes;
    </script>

1.第一种做法比较麻烦,console.log之后它打印出来的不光是li,还有里面的文本元素(空格换行之类的),你要是想只要元素还得去遍历获取。

2.parentNode.children(非标准,但是兼容)用的多

console.log(ul.children);

3.获取第一个子元素和最后一个子元素

1.获取第一个子元素:parentNode.firstChild

获取最后一个子元素:parentNode.lastChild

跟childNodes一样,包括空格换行啥的,不好用

2.获取第一个子元素:parentNode.firstElementChild

获取最后一个子元素:parentNode.lastElementChild

(但是只有ie9以上才支持)

3.非常好用的办法!

获取第一个子元素:parentNode.children[0];

获取最后一个子元素:parentNode.children[parentNode.children.length-1];

案例:下拉菜单
<style>
 .nav{
     margin: 100px 200px;
     text-align: center;
 }
li{
    list-style: none;
}
a {
    color: #666;
    text-decoration: none;
        /*超链接去掉下划线并变色*/
    text-align: center;
}
.box{
    float: left;
    /* margin-right: 20px; */
    width: 100px;
}
ul{
    padding: 0;
}
.box ul li{
    border: 1px solid rgb(255, 166, 0);
    border-top: 0;
}
.box ul{
    display: none;
}
</style>
<body>
    <div class="nav">
        <li class="box">
            <a href="">微博</a>
            <ul>
                <li><a href="">私信</a> </li>
                <li><a href="">评论</a> </li>
                <li><a href="">@我</a></li>
            </ul>
        </li>
        <li class="box">
            <a href="">微博</a>
            <ul>
                <li><a href="">私信</a> </li>
                <li><a href="">评论</a> </li>
                <li><a href="">@我</a></li>
            </ul>
        </li>
        <li class="box">
            <a href="">微博</a>
            <ul>
                <li><a href="">私信</a> </li>
                <li><a href="">评论</a> </li>
                <li><a href="">@我</a></li>
            </ul>
        </li>
        <li class="box">
            <a href="">微博</a>
            <ul>
                <li><a href="">私信</a> </li>
                <li><a href="">评论</a> </li>
                <li><a href="">@我</a></li>
            </ul>
        </li>
        
       
    </div>
<script>
      var boxs=document.querySelectorAll('.box');
      //console.log(boxs[0].children[0]);
      for(var i=0;i<boxs.length;i++)
      {
        boxs[i].onmouseover=function(){
            this.children[1].style.display='block';
        }
        boxs[i].onmouseout=function(){
            this.children[1].style.display='';
        }
      }
      
    </script>

(图上没有显示鼠标)

还是比较简单的,就是我在设置函数的时候我设置的是点击boxs的第一个孩子a微博,然后下面那个用this就不太行了,因为a和ul是兄弟的关系,我之前的经验是看他点击了哪个,不要给他的父元素去设置,但是还没学兄弟有点不太行,还好给做出来了。

4.获取兄弟节点

1.带空格和换行,没什么大用

2.有兼容性问题

3.好用!但是实际上用兄弟用的不多

二、节点的增删

1.创建并添加元素节点(发表新的评论)

(1)父元素.appendChild(要添加的元素)

<body>
   <ul></ul>
    <script>
        //给body里面没有的创建一个并获取这个元素
      var li=document.createElement('li');
      var ul=document.querySelector('ul');
      ul.appendChild(li);
    </script>
</body>

类似于数组的push,将子元素放到父元素的末尾

(2)父元素.insertBefore(要添加的元素节点,添加到谁前面)

 <ul>
       <li class="hh">123</li>
   </ul>
    <script>
        //给body里面没有的创建一个并获取这个元素
      var li=document.createElement('li');
      var ul=document.querySelector('ul');
      var hh=document.querySelector('.hh');
      //ul.appendChild(li);//到父元素最后一位
      ul.insertBefore(li,hh);
     //ul.insertBefore(li,ul.children[0]);
    </script>

案例:简单添加留言

核心思路:点击按钮之后,就创建一个li,然后添加到ul中去,同时还是把文本域的文字innerH TML给li

<style>
 
li{
    list-style: none;
    background-color: pink;
    width: 500px;
    margin-bottom: 10px;
}
a {
    color: #666;
    text-decoration: none;
        /*超链接去掉下划线并变色*/
    text-align: center;
}

</style>
<body>
    <textarea name="" id="" cols="30" rows="10"></textarea>
    <button>提交</button>
   <ul>
       <li>123</li>
   </ul>
    <script>
        //给body里面没有的创建一个并获取这个元素
        var content=document.querySelector('textarea');
        var ul=document.querySelector('ul');
         var button=document.querySelector('button');
         button.onclick=function(){
             if(content.value=='')
             {
                 alert('您没有输入任何东西');
             }
             else{
                var li=document.createElement('li');
                ul.appendChild(li);//到父元素最后一位
                li.innerHTML=content.value;
             }
      }
      
      
    </script>

这里边注意textarea里面的内容是value

2.删除元素节点

(1)使用父元素.removeChild(子元素)

<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul=document.querySelector('ul');
        ul.removeChild(ul.children[0]);
    </script>
</body>

(2)添加留言和删除留言

这次的删除按钮是在每条留言的后面,也就是和li在一个盒子里,在li.innerHTML=content.value还得加上一个链接a,但是a里面放#也不合适,那就是另一个页面了,阻止链接跳转是javascript:void(0);或者javascript:;

<body>
    <textarea name="" id="" cols="30" rows="10"></textarea>
    <button class="tijiao">提交</button>
    
   <ul>
       <!-- <li>123</li> -->
   </ul>
    <script>
        //给body里面没有的创建一个并获取这个元素
        var content=document.querySelector('textarea');
        var ul=document.querySelector('ul');
         var tijiao=document.querySelector('.tijiao');
         tijiao.onclick=function(){
             if(content.value=='')
             {
                 alert('您没有输入任何东西');
             }
             else{
                var li=document.createElement('li');
                ul.insertBefore(li,ul.children[0]);//到父元素最后一位
                li.innerHTML=content.value+"<a href='javascript:;'>删除</a>";
                var as=document.querySelectorAll('a');
                for(var i=0;i<as.length;i++)
               {
                    as[i].onclick=function(){
             
                    ul.removeChild(this.parentNode);
                     }
            
                }
             }
      }     
    </script>
</body>

我有点纳闷为啥后面的点击删除事件还有获取a、for循环啥的要写在else里面呢?

因为如果放在外面的话,没有执行点击提交按钮的时候就有var as生成了,那那个时候的as就是空的,后来的a标签虽然生成了,但是as获取的时候的a是以前空的a,所以不行。

3.复制元素节点

(1)node.cloneNode()

   <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
var ul=document.querySelector('ul');
        var li1=ul.children[0].cloneNode();
        ul.appendChild(li1);

查看元素发现里面没有数字1是为啥呢,看下面

(2)浅拷贝和深拷贝

node.cloneNode()括号里默认是false,也就是浅拷贝,只copy元素不copy内容
node.cloneNode(true),如果括号里是true就是深拷贝,copy元素和内容

三、动态生成表格

css和学生数据datas部分
li{
    list-style: none;
    background-color: pink;
    width: 500px;
    margin-bottom: 10px;
}
a {
    color: #666;
    text-decoration: none;
        /*超链接去掉下划线并变色*/
}
table {
    width: 400px;
    margin: 100px auto;
    text-align: center;
    border-collapse: collapse;
}

th,
td {
    border: 1px solid #333;
}

thead tr {
    height: 40px;
    background-color: #ccc;
}

tbody tr {
    height: 30px;
}


</style>
<body>
    <table>
        <thead>
            <tr>
                <th>姓名</th>
                <th>科目</th>
                <th>成绩</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>

        </tbody>
    </table>
    <script>
        var datas=[
            {
                names:'a',
                subject:'javescript',
                score:100
            },
            {
                names:'b',
                subject:'javescript',
                score:10
            },
            {
                names:'c',
                subject:'javescript',
                score:80
            },
            {
                names:'d',
                subject:'javescript',
                score:78
            },

        ]
        

        
    </script>
创建行和单元格:有多少人就创建多少行,循环来做
var tbody=document.querySelector('tbody');
        for(var i=0;i<datas.length;i++){
            //var td=document.querySelector('tbody').createElement('td');这样写不对
            var tr=document.createElement('tr');
            tbody.appendChild(tr);
            for(var k in datas[i])//k是个属性,obj(data[i])是对象,是数组中的每个对象
            {
                var td=document.createElement('td');
                tr.appendChild(td);
            }//最后的那个操作先不管
            
        }
把对象里面的属性值(obj[k])给td,(k是属性名)
for(var k in datas[i])//k是个属性,obj(data[i])是对象,是数组中的每个对象
            {
                var td=document.createElement('td');
                td.innerHTML=datas[i][k];
                tr.appendChild(td);
            }//最后的那个操作先不管

这里的datas[i][k]后面就不需要value,因为datas[i][k]就是那个值了,不像textarea它是那个框,得value才是里面的值呢

添加删除操作

这会也不用担心添加第四个会不会下面的乱跑了,因为第一个for循环控制第几行的,这样在第二个for循环外面(第一个for里面)创建一个create删除就行

var td=document.createElement('td');
            td.innerHTML='<a href="javascript:;">删除</a>'
            tr.appendChild(td);
让删除键起作用

因为整个第一个for都是在创建表格,现在创建完了就该把删除的代码写在第一个for下面了

var as=document.querySelectorAll('a');
        for(var i=0;i<as.length;i++)
            {
                as[i].onclick=function(){
                    tbody.removeChild(this.parentNode.parentNode);
                }
            }

找了半天错,结果是在removeChild后面加了=

四、innerHTML和createElement

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值