DOM二(属性操作、自定义属性、节点层级)

属性操作

获取属性值

在DOM对象中可以使用“element.属性”的方式来获取内置的属性值,但是DOM对象并不能直接使用点语法获取到自定义属性的值,那么如何获取自定义属性值呢?

在DOM中,可以使用getAttribute('属性')方法来返回指定元素的属性值。

练习

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="domo" index='1' class="nav"></div>
    <script>
        var div = document.querySelector('div');
        console.log(div.id);
        console.log(div.index);
        console.log(div.getAttribute('index'));//获取元素属性值
    </script>
</body>
</html>

在这里插入图片描述

设置属性值

在DOM对象中可以使用“element.属性= '值'”的方式来设置内置的属性值,并且针对于自定义属性,提供了“element.setAttribute('属性', '值')”的方式进行获取。

值得一提的是,设置了自定义属性的标签,在浏览器中的HTML结构中可以看到该属性。

移除属性值

在DOM中使用“element.removeAttribute('属性')”的方式来移除元素属性。接下来,通过案例演示如何移除属性值。

练习

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div></div>
    <button>移除属性</button>
    <script>
        var div = document.querySelector('div');
        div.id = 'text';
        div.setAttribute('class',"nva");
        div.setAttribute('index',1001);//添加属性

        var btn = document.querySelector('button')
        btn.onclick = function(){
            div.removeAttribute('index');//移除属性
        }
    </script>
</body>
</html>

在这里插入图片描述

自定义属性

设置属性值

一般的自定义属性可以通过getAttribute('属性')方法来获取,但是有些自定义属性很容易引起歧义,不容易判断是元素的自带属性还是自定义属性。因此,HTML5新增了自定义属性的规范,在HTML5中规定通过“data-属性名”的方式设置自定义属性。

元素的“data-*”自定义属性有两种设置方式,分别如下:
1、在HTML中设置自定义属性


// 在div元素上设置data-index属性
<div data-index="2"></div>


2、在JavaScript中设置自定义属性

在JavaScript代码中,可以通过setAttribute(‘属性’, 值)或者“元素对象.dataset.属性名=‘值’”两种方式设置自定义属性。需要注意的是,通过后者的方式只能设置以“data-”开头的自定义属性。

<body>
  <div></div>
  <script>
    var div = document.querySelector('div');
    div.dataset.index = '2';
     div.setAttribute('data-name', 'andy');
  </script>
</body>

获取属性值

在DOM操作中,提供了两种获取属性值的方式。

第1种:通过getAttribute()方式,该方式可以获取内置属性或者自定义属性。

第2种:使用HTML5新增的“element.dataset.属性”或者“element.dataset['属性'] ”方式(有兼容性问题)。

练习

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
       <p data-index = '111'></p>  <!-- data-是前缀,属性名是index -->
       <button>获取属性</button>
       <script>
           var p = document.querySelector('p');
           p.dataset.class = 'nav';
           p.setAttribute('data-name','孔明');

           var btn = document.querySelector('button');
           btn.onclick = function(){
               console.log('Name:',p.dataset.name);
               console.log('Index:',p.dataset['index']);
           }
       </script>
    </div>
</body>
</html>

节点层级

获取父级节点

在JavaScript中,可以使用parentNode属性来获得离当前元素的最近的一个父节点,如果找不到父节点就返回为 null

语法格式为:obj.parentNode,obj是一个DOM对象。

获取子级节点

在JavaScript中,可以使用childNodes属性或者children属性两种方式来获得当前元素的所有子节点的集合,接下来我们就分别介绍这两种方式的用法。

方式1

childNodes属性获得的是当前元素的所有子节点的集合,该集合为即时更新的集合。

注意:

childNodes属性返回的是NodeList对象的集合,返回值里面包含了元素节点、文本节点等其他类型的节点

方式2

children是一个可读的属性,返回所有子元素节点。children只返回子元素节点,其余节点不返回,目前各大浏览器都支持该属性,在实际开发中推荐使用children。

两者的区别

childNodes属性与children属性虽然都可以获取某元素的子元素,但是两者之间有一定的区别。前者用于节点操作,返回值是NodeList对象集合,后者用于元素操作,返回的是HTMLCollection对象集合。

方式3

使用firstChild属性lastChild属性获取子节点,前者返回第一个子节点,后者返回的是最后一个子节点,如果找不到则返回null。需要注意的是它们的返回值包括文本节点和元素节点等。

方式4

使用firstElementChild属性lastElementChild属性获取子元素节点,前者返回第一个子元素节点,后者返回最后一个子元素节点,如果找不到则返回null。需要注意的是,这两个属性有兼容性问题,IE9以上才支持。

注意

实际开发中,firstChild 和lastChild 包含其他节点,操作不方便,而firstElementChild和lastElementChild又有兼容性问题,为了解决兼容性问题,在实际开发中通常使用“obj.children[索引] ”的方式来获取子元素节点。

obj.children[0]			   // 获取第一个子元素节点
obj.children[obj.children.length - 1]   // 获取最后一个子元素节点

小练习

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="demo">
        <div class="box">
            <h2>北京大学</h2>
            <span class="child">西安交通大学</span>
            <p>清华大学</p>
        </div>
    </div>
    <div>
        <ul>
            <li>红楼梦</li>
            <li>水浒传</li>
            <li>三国演义</li>
            <li>西游记</li>
        </ul>
    </div>
    <script>
        var child = document.querySelector('.child');
        console.log(child.parentNode)

        var ul = document.querySelector('ul');
        var lis = ul.querySelectorAll('li');

        console.log(lis)
        console.log("通过childNodes的子节点:",ul.childNodes)
        console.log("children:",ul.children)
        console.log("ul第一个子节点的类型:",ul.children[0].nodeType)
        console.log("ul第二个子节点的类型:",ul.children[1].nodeType)

        console.log("ul的第一个子节点:",ul.firstChild);
        console.log("ul的最后一个子节点:",ul.lastChild);

        console.log("ul的第一个子元素节点:",ul.firstElementChild);
        console.log("ul的最后一个子元素节点:",ul.lastElementChild);

        var span = document.querySelector('.child');
        console.log("span的下一个兄弟元素节点:",span.nextElementSibling)
        console.log("span的前一个兄弟元素节点:",span.previousElementSibling)
    </script>
</body>
</html>

在这里插入图片描述

获取兄弟节点

1、使用nextSibling属性获得下一个兄弟节点。

2、使用previousSibling属性获得上一个兄弟节点。

它们的返回值包含元素节点或者文本节点等。如果找不到,就返回null

3、使用nextElementSibling返回当前元素的下一个兄弟元素节点。

4、previousElementSibling属性返回当前元素的上一个兄弟元素节点,如果找不到则返回null。

需要注意的是,这两个属性有兼容性问题,IE9以上才支持。

注意

实际开发中,nextSibling和previousSibling属性返回值都包含其他节点,操作不方便,而nextElementSibling和previousElementSibling又有兼容性问题。为了解决兼容性问题,在实际开发中通常使用封装函数来处理兼容性。

下拉菜单制作

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    li{
        list-style-type:none ;
    }
    a{
        text-decoration: none;
        font-size: 14px;
    }
    .nav{
        margin: 100px;
    }
    .nav>li{
        position: relative;
        float: left;
        width: 80px;
        height: 41px;
        text-align: center;
    }
    .nav li a{
        display: block;
        width: 100%;
        height: 100%;
        line-height: 41px;
        color: #333;
    }
    .nav>li>a:hover{
        background-color: #eee;
    }
    .nav ul{
        display: none;
        position: absolute;
        top: 41px;
        left: 0;
        width: 100%;
        border-left: 1px solid #fecc5b;
        border-right: 1px solid #fecc5b;
    }
    .nav ul li{
        border-bottom: 1px solid #fecc5b;
    }
    .nav ul li a:hover{
        background-color: #fff5da;
    }
</style>
<body>
    <ul class="nav">
        <li>
            <a href="#">微博</a>
                <ul>
                    <li>
                        <a href="#">私信</a>
                    </li>
                    <li>
                        <a href="#">评论</a>
                    </li>
                    <li>
                        <a href="#">@我</a>
                    </li>
                </ul>
        </li>
        <li>
            <a href="#">留言板</a>
            <ul>
                <li>
                    <a href="#">私信</a>
                </li>
                <li>
                    <a href="#">评论</a>
                </li>
                <li>
                    <a href="#">@我</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">电话</a>
            <ul>
                <li>
                    <a href="#">私信</a>
                </li>
                <li>
                    <a href="#">评论</a>
                </li>
                <li>
                    <a href="#">@我</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">邮箱</a>
            <ul>
                <li>
                    <a href="#">私信</a>
                </li>
                <li>
                    <a href="#">评论</a>
                </li>
                <li>
                    <a href="#">@我</a>
                </li>
            </ul>
        </li>
    </ul>
    <script>

        var nav = document.querySelector('.nav');
        var lis = nav.children;

        for(let 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>
</body>
</html>

在这里插入图片描述

节点操作

创建节点

在DOM中,使用document.createElement('tagName')方法创建由tagName指定的HTML元素,也称为动态创建元素节点。

动态创建元素节点的3种常见方式如下:

1、document.write()创建元素,如果页面文档流加载完毕,再调用会导致页面重
.。
2、element.innerHTML将内容写入某个DOM节点,不会导致页面全部重绘

3、document.createElement()创建多个元素效率稍微低一点,但是结构更加清晰

添加和删除节点

DOM中,提供了node.appendChild()和node.insertBefore()方法用于添加节点,node. removeChild(child)用于删除节点。

下面讲解这3种方法的使用。

1、appendChild()方法,将一个节点添加到指定父节点的子节点列表末尾

2、insertBefore(child, 指定元素)方法,将一个节点添加到父节点的指定子节点前面

3、removeChild(child)用于删除节点,该方法从DOM中删除一个子节点,返回删除的节点

简易留言板的制作

案例分析:利用节点的创建、添加和删除相关知识完成一个简易的留言板功能。在页面中实现单击“发布”按钮动态创建一个li元素,添加到ul里面。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    body{
        padding: 100px;

    }
    textarea{
        width: 200px;
        height: 100px;
        border: solid 1px pink;
        outline: none;
        resize: none;
    }
    ul{
        margin-top: 50px;
    }
    li{
        width: 300px;
        /* word-wrap: break-word; */
        padding: 5px;
        margin: 15px 0;
        font-size: 15px;
        background-color: #eee;
    }
    li a{
        float: right;
    }
</style>
<body>
    <textarea></textarea>
    <button>发布</button>
    <ul></ul>
    <script>
        var text = document.querySelector('textarea');
        var but = document.querySelector('button');
        var ul  =document.querySelector('ul');

        but.onclick = function(){
            if(text.value ==''){
                alert('没有输入内容');
            }else{
                //创建子元素
                var li = document.createElement('li');

                li.innerHTML = text.value +'<a href="javascript:;">删除</a>'//空语句页面不发生跳转
                text.value = '';

                ul.insertBefore(li,ul.children[0]);
                var as = document.querySelectorAll('a');

                for(var i = 0;i<as.length;i++){
                    as[i].onclick = function(){
                        ul.removeChild(this.parentNode)//删除父节点(li)
                    }
                }
            }
        }
    </script>
</body>
</html>

在这里插入图片描述

复制节点

在DOM中,提供了node.cloneNode()方法,返回调用该方法的节点的一个副本,也称为克隆节点或者拷贝节点。

语法为“需要被复制的节点.cloneChild(true/false) ”

如果参数为空或false,则是浅拷贝,即只复制节点本身,不复制里面的子节点。

如果括号参数为true,则是深拷贝,即会复制节点本身及里面所有的子节点。

复制第一个子节点练习

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul id = 'mylist'>
        <li>苹果</li>
        <li>橙子</li>
        <li>橘子</li>
    </ul>
    <ul id="op"></ul>
    <button onclick="fun()">克隆</button>

    <script>
        function fun(){
            //找到mylist的第一个子节点
            var item = document.querySelector('#mylist').firstElementChild;

            //对子节点进行复制
            var cloneItem = item.cloneNode(true);

            document.querySelector('#op').appendChild(cloneItem);

        }

    </script>
</body>
</html>

在这里插入图片描述

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力做一只合格的前端攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值