Fork me on GitHub

JavaScript之DOM操作-02

4.5 排他思想

如果有同一组元素,我们想要某一个元素实现某种样式,需要用到循环的排他算法:

  1. 所有元素全部清楚样式(干掉其他人)
  2. 给当前元素设置样式(留下我自己)
  3. 注意顺序不能颠倒,首先干掉其他人,再设置自己
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
    // 1. 获取所有按钮元素
    var btns = document.getElementsByTagName('button');
    // btns得到的是伪数组  里面的每一个元素 btns[i]
    for (var i = 0; i < btns.length; i++) {
        btns[i].onclick = function() {
            // (1) 我们先把所有的按钮背景颜色去掉  干掉所有人
            for (var i = 0; i < btns.length; i++) {
                btns[i].style.backgroundColor = '';
            }
            // (2) 然后才让当前的元素背景颜色为pink 留下我自己
            this.style.backgroundColor = 'pink';
 
        }
    }
    //2. 首先先排除其他人,然后才设置自己的样式 这种排除其他人的思想我们成为排他思想
</script> 

案例1:百度换肤

案例分析:

  1. 这个案例练习的是给一组元素注册事件
  2. 给4个小图片利用循环注册点击事件
  3. 当我们点击了这个图片,让我们页面背景改为当前的图片
  4. 核心算法:把当前图片的src路径取过来,给body作为背景即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    <style>
        * {
            margin: 0;
            padding: 0;
        }
         
        body {
            background: url(images/1.jpg) no-repeat center top;
        }
         
        li {
            list-style: none;
        }
         
        .baidu {
            overflow: hidden;
            margin: 100px auto;
            background-color: #fff;
            width: 410px;
            padding-top: 3px;
        }
         
        .baidu li {
            float: left;
            margin: 0 1px;
            cursor: pointer;
        }
         
        .baidu img {
            width: 100px;
        }
    </style>
</head>
 
<body>
    <ul class="baidu">
        <li><img src="images/1.jpg"></li>
        <li><img src="images/2.jpg"></li>
        <li><img src="images/3.jpg"></li>
        <li><img src="images/4.jpg"></li>
    </ul>
    <script>
        // 1. 获取元素
        var imgs = document.querySelector('.baidu').querySelectorAll('img');
        // console.log(imgs);
        // 2. 循环注册事件
        for (var i = 0; i < imgs.length; i++) {
            imgs[i].onclick = function() {
                // this.src 就是我们点击图片的路径   images/2.jpg
                // console.log(this.src);
                // 把这个路径 this.src 给body 就可以了
                document.body.style.backgroundImage = 'url(' + this.src + ')';
            }
        }
    </script>
</body>

案例2:表格隔行换色

案例分析

  1. 鼠标onmouseover 鼠标离开onmouseout
  2. 核心思路:鼠标经过tr行,当前的行变背景颜色,鼠标离开去掉当前的背景颜色
  3. 注意:第一行(thead里面的行)不需要变换颜色,因此我们获取的是tbody里面的行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
    // 1.获取元素 获取的是 tbody 里面所有的行
    var trs = document.querySelector('tbody').querySelectorAll('tr');
    // 2. 利用循环绑定注册事件
    for (var i = 0; i < trs.length; i++) {
        // 3. 鼠标经过事件 onmouseover
        trs[i].onmouseover = function() {
                // console.log(11);
                this.className = 'bg';
            }
            // 4. 鼠标离开事件 onmouseout
        trs[i].onmouseout = function() {
            this.className = '';
        }
    }
</script>

案例3:表单全选取消全选案例

业务需求:

  1. 点击上面全选复选框,下面所有的复选框都选中(全选)
  2. 再次点击全选复选框,下面所有的复选框都不选中(取消全选)
  3. 如果下面复选框全部选中,上面全选按钮就自动选中
  4. 如果下面复选框有一个没有选中,上面全选按钮就不选中
  5. 所有复选框一开始默认都没选中状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<script>
    //1.全选和取消全选的做法:让下面所有复选框的checked属性(选中状态)  跟随  全选按钮即可
    //获取元素
    var j_cbAll = document.querySelector('#j_cbAll'); //全选按钮
    var j_tbs = document.querySelector('#j_tb').querySelectorAll('input'); //下面所有的复选框
    //注册事件
    j_cbAll.onclick = function() {
            //this.checked  它可以得到当前复选框的选中状态如果是true 就是选中 ,如果是false 就是未选中
            console.log(this.checked);
            for (var i = 0; i < j_tbs.length; i++) {
                j_tbs[i].checked = this.checked;
            }
        }
        //2. 下面复选框需要全部选中,上面全选才能被选中的做法:
        //给下面所有的复选框都绑定点击事件,每次点击,都要循环查看下面所有的复选框是否有没被选中的,如果有一个没被选中,上面的全选就不选中
    for (var i = 0; i < j_tbs.length; i++) {
        j_tbs[i].onclick = function() {
            // flag 控制全选按钮是否选中
            var flag = true;
            // 每次点击下面的复选框都要循环检查者4个小按钮是否全被选中
            for (var i = 0; i < j_tbs.length; i++) {
                if (!j_tbs[i].checked) {
                    flag = false;
                    break;
                    // 退出for循环 这样可以提高执行效率 因为只要有一个没有选中,剩下的就无需循环判断了
                }
            }
            // console.log(flag);
            j_cbAll.checked = flag;
        }
    }
</script>

4.6 自定义属性操作

1、获取属性值
element.属性 获取属性值
element.getAttribute(‘属性’)
区别:

element.属性 获取内置属性值(元素本身自带的属性)
element.getAttribute(‘属性’) 主要获得自定义的属性,程序员自定义的属性
2、设置属性值
element.属性 = ‘值’ 设置内置属性值
element.setAttribute(‘属性’,‘值’)
区别:

element.属性 设置内置属性值
element.setAttribute(’属性‘);主要设置自定义的属性
3、移除属性
element.removeAttribute(‘属性’);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="demo" index="1" class="nav"></div>
<script>
    var div = document.querySelector('div');
    // 1. 获取元素的属性值
    // (1) element.属性
    console.log(div.id);
    //(2) element.getAttribute('属性')  get得到获取 attribute 属性的意思 我们程序员自己添加的属性我们称为自定义属性 index
    console.log(div.getAttribute('id'));
    console.log(div.getAttribute('index'));
    // 2. 设置元素属性值
    // (1) element.属性= '值'
    div.id = 'test';
    div.className = 'navs';
    // (2) element.setAttribute('属性', '值');  主要针对于自定义属性
    div.setAttribute('index', 2);
    div.setAttribute('class', 'footer'); // class 特殊  这里面写的就是class 不是className
    // 3 移除属性 removeAttribute(属性)   
    div.removeAttribute('index');
</script>

案例:tab栏切换

1
2
3
4
5
6
7
8
9
当鼠标点击上面相应的选项卡(tab),下面内容跟随变化
     
 案例分析:
    1.tab栏切换有2个大的模块
    2.上面的模块选项卡,点击某一个,当前这一个底色会是红色,其余不变(排他思想)修改类名的方式
    3.下面的模块内容,会跟随上面的选项卡变化。所以下面模块变化写到点击事件里面
    4.规律:下面的模块显示内容和上面的选项卡一一对应,相匹配
    5.核心思路:给上面的tab_list里面的所有小li添加自定义属性,属性值从0开始编号
    6.当我们点击tab_list里面的某个小li,让tab_con里面对应序号的内容显示,其余隐藏(排他思想)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<style>
    * {
        padding: 0;
        margin: 0;
    }
     
    .tab {
        width: 1000px;
        margin: 100px auto;
    }
     
    .tab_list ul {
        list-style-type: none;
    }
     
    .tab_list {
        height: 38px;
        border: 1px solid #ccc;
        background-color: #f1f1f1;
    }
     
    .tab_list li {
        float: left;
        height: 38px;
        line-height: 38px;
        padding: 0 20px;
        text-align: center;
        cursor: pointer;
    }
     
    .tab_list .current {
        background-color: #c81623;
        color: #fff;
    }
     
    .item {
        display: none;
    }
</style>
 
<body>
    <div class="tab">
        <div class="tab_list">
            <ul>
                <li class="current">商品介绍</li>
                <li>规格与包装</li>
                <li>售后保障</li>
                <li>商品评价(50000)</li>
                <li>手机社区</li>
            </ul>
        </div>
        <div class="tab_con">
            <div class="item" style="display: block;">
                商品介绍模块内容
            </div>
            <div class="item">
                规格与包装模块内容
            </div>
            <div class="item">
                售后保障模块内容
            </div>
            <div class="item">
                商品评价(50000)模块内容
            </div>
            <div class="item">
                手机社区模块内容
            </div>
        </div>
    </div>
    <script>
        //获取元素
        var ul = document.querySelector('ul');
        var lis = ul.querySelectorAll('li');
        var items = document.querySelectorAll('.item');
        //for循环绑定点击事件
        for (var i = 0; i < lis.length; i++) {
            //开始给5个小li设置索引号
            lis[i].setAttribute('index', i);
            lis[i].onclick = function() {
                // 1. 上面的模块选项卡,点击某一个,当前这一个底色会是红色,其余不变(排他思想) 修改类名的方式
 
                //干掉所有人,其余的li清除 class这个类
                for (var i = 0; i < lis.length; i++) {
                    lis[i].className = '';
                }
                //留下我自己
                this.className = 'current';
                //2.下面的显示内容模块
                var index = this.getAttribute('index');
                //干掉所有人 让其余的item 这些div隐藏
                for (var i = 0; i < items.length; i++) {
                    items[i].style.display = 'none';
                }
                //留下我自己  让对应的item 显示出来
                items[index].style.display = 'block';
            }
        }
    </script>
</body>

4.7 H5自定义属性

自定义属性的目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中  

自定义属性获取是通过getAttribute(‘属性’)获取

但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性

H5给我们新增了自定义属性:

1.设置H5自定义属性

H5规定自定义属性data-开头做为属性名并且赋值

<div data-index='1'></div>

或者使用js设置

element.setAttribute(‘data-index’,2)  

2.获取H5自定义属性

    • 兼容性获取 element.getAttribute(‘data-index’);
    • H5新增element.dataset.index 或者 element.dataset[‘index’]
      ie 11才支持
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div getTime="20" data-index="2" data-list-name="andy"></div>
<script>
    var div = document.querySelector('div');
    // console.log(div.getTime);
    console.log(div.getAttribute('getTime'));
    div.setAttribute('data-time', 20);
    console.log(div.getAttribute('data-index'));
    console.log(div.getAttribute('data-list-name'));
    // h5新增的获取自定义属性的方法 它只能获取data-开头的
    // dataset 是一个集合里面存放了所有以data开头的自定义属性
    console.log(div.dataset);
    console.log(div.dataset.index);
    console.log(div.dataset['index']);
    // 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法
    console.log(div.dataset.listName);
    console.log(div.dataset['listName']);
</script>

五:节点操作

5.1 为什么学习节点操作

获取元素通常使用两种方式:

1、利用DOM提供的方法获取元素  

  • document.getElementByld()
  • document.getElementsByTagName()
  • document.querySelector等
  • 逻辑性不强,繁琐

2、利用节点层级关系获取元素  

  • 利用父子兄弟节点关系获取元素
  • 逻辑性强,但是兼容性差
1
这两种方式都可以获取元素节点,我们后面都会使用,但是节点操作更简单

5.2 节点概述

网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM中,节点使用node表示

HTML DOM树中的所有节点均可通过Javascript 进行访问,所有HTML元素(节点)均可被修改,也可以创建或删除。

 

 

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

  • 元素节点 nodeType 为 1
  • 属性节点 nodeType 为 2
  • 文本节点 nodeType 为 3(文本节点包含文字、空格、换行等)

 我们在实际开发中,节点操作主要操作的是元素节点

5.3 节点层级

利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄层级关系

1、父级节点

1
node.parentNode
1
2
parentNode 属性可返回某节点的父节点,注意是最近的一个父节点
如果指定的节点没有父节点则返回null
1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="demo">
       <div class="box">
           <span class="erweima">×</span>
       </div>
   </div>
 
   <script>
       // 1. 父节点 parentNode
       var erweima = document.querySelector('.erweima');
       // var box = document.querySelector('.box');
       // 得到的是离元素最近的父级节点(亲爸爸) 如果找不到父节点就返回为 null
       console.log(erweima.parentNode);
   </script>

2、子节点

1
parentNode.childNodes(标准)

parentNode.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合  

注意:返回值里面包含了所有的子节点,包括元素节点,文本节点等。

如果只想要获得里面的元素节点,则需要专门处理。 所以我们一般不提倡使用childNodes  

1
2
3
4
5
6
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]);}
}

 

1
2.parentNode.children(非标准)

parentNode.children是一个只读属性,返回所有的子元素节点。其余结点不返回

虽然children是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<ul>
     <li>我是li</li>
     <li>我是li</li>
     <li>我是li</li>
     <li>我是li</li>
 
 </ul>
 <ol>
     <li>我是li</li>
     <li>我是li</li>
     <li>我是li</li>
     <li>我是li</li>
 </ol>
  
 <script>
     // DOM 提供的方法(API)获取
     var ul = document.querySelector('ul');
     var lis = ul.querySelectorAll('li');
     // 1. 子节点  childNodes 所有的子节点 包含 元素节点 文本节点等等
     console.log(ul.childNodes);
     console.log(ul.childNodes[0].nodeType);
     console.log(ul.childNodes[1].nodeType);
     // 2. children 获取所有的子元素节点 也是我们实际开发常用的
     console.log(ul.children);
 </script>

 

1
3. parentNode.firstChild

 firstChild返回第一个子节点,找不到则返回null。同样,也是包含所有的节点 

1
4.parentNode.lastChild

 lastChild返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点 

1
5.parentNode.firstElementChild

firstElementChild 返回第一个子元素节点,找不到则返回null  

1
6.parentNode.lastElementChild

lastElementChild返回第一个子元素节点,找不到则返回null  

注意:这两个方法有兼容性问题,IE9 以上才支持。

实际开发中,firstChild和lastChild包含其他节点,操作不方便,而firstElementChild 和lastElementChild又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?

解决方案:

  • 如果想要第一个子元素节点,可以使用 parentNode.chilren[0]
  • 如果想要最后一个子元素节点,可以使用 parentNode.chilren[parentNode.chilren.length - 1]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<ol>
    <li>我是li1</li>
    <li>我是li2</li>
    <li>我是li3</li>
    <li>我是li4</li>
    <li>我是li5</li>
</ol>
<script>
    var ol = document.querySelector('ol');
    // 1. firstChild 第一个子节点 不管是文本节点还是元素节点
    console.log(ol.firstChild);
    console.log(ol.lastChild);
    // 2. firstElementChild 返回第一个子元素节点 ie9才支持
    console.log(ol.firstElementChild);
    console.log(ol.lastElementChild);
    // 3. 实际开发的写法  既没有兼容性问题又返回第一个子元素
    console.log(ol.children[0]);
    console.log(ol.children[ol.children.length - 1]);
</script>

案例:下拉菜单

案例分析:

  1. 导航栏里面的li都要有鼠标经过效果,所以需要循环注册鼠标事件
  2. 核心原理:当鼠标经过的li , 里面的第二个孩子ul显示,当鼠标离开,则ul隐藏
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    <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>
</head>
 
<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>
        // 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>

3、兄弟节点

1
1.node.nextSibling

  nextSibling 返回当前元素的下一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点

1
2.node.previousSibling

 previousSibling 返回当前元素上一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点 

1
3.node.nextElementSibling

nextElementSibling返回当前元素下一个兄弟元素节点,找不到则返回null  

1
4.node.previousElmentSibling

previousElementSibling返回当前元素上一个兄弟节点,找不到则返回null  

注意:这两个方法有兼容性问题,IE9以上才支持

 

问:如何解决兼容性问题?

答:自己封装一个兼容性的函数

1
2
3
4
5
6
7
8
9
10
11
<script>
        function getNextElementSibling(element) {
            var el = element;
            while (el = el.nextSibling) {
                if (el.nodeType === 1) {
                    return el;
                }
            }
            return null;
        }
</script>

 

1
2
3
4
5
6
7
8
9
10
11
<div>我是div</div>
   <span>我是span</span>
   <script>
       var div = document.querySelector('div');
       // 1.nextSibling 下一个兄弟节点 包含元素节点或者 文本节点等等
       console.log(div.nextSibling);
       console.log(div.previousSibling);
       // 2. nextElementSibling 得到下一个兄弟元素节点
       console.log(div.nextElementSibling);
       console.log(div.previousElementSibling);
   </script>

5.4 创建节点 

1
document.createElement('tagName')

document.createElement()方法创建由 tagName 指定的HTML元素。

因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点

1
1.node.appendChild(child)

 node.appendChild()方法将一个节点添加到指定父节点的子节点列表末尾 。类似于css里面的after伪元素 

1
2.node.insertBefore(child,指定元素)

 node.insertBefore()方法将一个节点添加父节点的指定子节点的前面。类似于css里面的before伪元素 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<ul>
      <li>123</li>
  </ul>
  <script>
      // 1. 创建节点元素节点
      var li = document.createElement('li');
      // 2. 添加节点 node.appendChild(child)  node 父级  child 是子级 后面追加元素  类似于数组中的push
      var ul = document.querySelector('ul');
      ul.appendChild(li);
      // 3. 添加节点 node.insertBefore(child, 指定元素);
      var lili = document.createElement('li');
      ul.insertBefore(lili, ul.children[0]);
      // 4. 我们想要页面添加一个新的元素 : 1. 创建元素 2. 添加元素
  </script>

案例:简单版发布留言案例

案例分析

  1. 核心思路:点击按钮之后,就动态创建一个li,添加到ul里面
  2. 创建li的同时,把文本域里面的值通过li.innderHTML赋值给li
  3. 如果想要新的留言后面显示就用appendChild如果想要前面显示就用insertBefore
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
    <style>
        * {
            margin: 0;
            padding: 0;
        }
         
        body {
            padding: 100px;
        }
         
        textarea {
            width: 200px;
            height: 100px;
            border: 1px solid pink;
            outline: none;
            resize: none;
        }
         
        ul {
            margin-top: 50px;
        }
         
        li {
            width: 300px;
            padding: 5px;
            background-color: rgb(245, 209, 243);
            color: red;
            font-size: 14px;
            margin: 15px 0;
        }
    </style>
</head>
 
<body>
    <textarea name="" id=""></textarea>
    <button>发布</button>
    <ul>
 
    </ul>
    <script>
        // 1. 获取元素
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');
        var ul = document.querySelector('ul');
        // 2. 注册事件
        btn.onclick = function() {
            if (text.value == '') {
                alert('您没有输入内容');
                return false;
            } else {
                // console.log(text.value);
                // (1) 创建元素
                var li = document.createElement('li');
                // 先有li 才能赋值
                li.innerHTML = text.value;
                // (2) 添加元素
                // ul.appendChild(li);
                ul.insertBefore(li, ul.children[0]);
            }
        }
    </script>
</body>

5.5 删除节点

1
node.removeChild(child)

 node.removeChild() 方法从DOM中删除一个子节点,返回删除的节点 

案例:删除留言案例

案例分析:

  1. 当我们把文本域里面的值赋给li的时候,多添加一删除的链接
  2. 需要把所有的链接获取过来,当我们点击当前的链接的时候,删除当前链接所在的li
  3. 阻止链接跳转需要添加javascript:void(0);或者javascript:;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<textarea name="" id=""></textarea>
    <button>发布</button>
    <ul>
 
    </ul>
    <script>
        // 1. 获取元素
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');
        var ul = document.querySelector('ul');
        // 2. 注册事件
        btn.onclick = function() {
            if (text.value == '') {
                alert('您没有输入内容');
                return false;
            } else {
                // console.log(text.value);
                // (1) 创建元素
                var li = document.createElement('li');
                // 先有li 才能赋值
                li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
                // (2) 添加元素
                // ul.appendChild(li);
                ul.insertBefore(li, ul.children[0]);
                // (3) 删除元素 删除的是当前链接的li  它的父亲
                var as = document.querySelectorAll('a');
                for (var i = 0; i < as.length; i++) {
                    as[i].onclick = function() {
                        // node.removeChild(child); 删除的是 li 当前a所在的li  this.parentNode;
                        ul.removeChild(this.parentNode);
                    }
                }
            }
        }
    </script>

5.6 复制节点(克隆节点)

1
node.cloneNode()

 node.cloneNode()方法返回调用该方法节点的一个副本。也称为克隆节点/拷贝节点 

1
2
3
4
5
6
7
<script>
        var ul = document.querySelector('ul');
        // 1. node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容
        // 2. node.cloneNode(true); 括号为true 深拷贝 复制标签复制里面的内容
        var lili = ul.children[0].cloneNode(true);
        ul.appendChild(lili);
    </script>

注意:

1.如果括号参数为空或者为false,则浅拷贝,即只克隆复制节点本身,不克隆里面的子节点

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

5.7 三种动态创建元素区别

  1. document.write()
  2. element.innerHTML
  3. document.createElement()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<button>点击</button>
   <p>abc</p>
   <div class="inner"></div>
   <div class="create"></div>
   <script>
       // window.onload = function() {
       //         document.write('<div>123</div>');
 
       //     }
       // 三种创建元素方式区别
       // 1. document.write() 创建元素  如果页面文档流加载完毕,再调用这句话会导致页面重绘
       // var btn = document.querySelector('button');
       // btn.onclick = function() {
       //     document.write('<div>123</div>');
       // }
 
       // 2. innerHTML 创建元素
       var inner = document.querySelector('.inner');
       // for (var i = 0; i <= 100; i++) {
       //     inner.innerHTML += '<a href="#">百度</a>'
       // }
       var arr = [];
       for (var i = 0; i <= 100; i++) {
           arr.push('<a href="#">百度</a>');
       }
       inner.innerHTML = arr.join('');
       // 3. document.createElement() 创建元素
       var create = document.querySelector('.create');
       for (var i = 0; i <= 100; i++) {
           var a = document.createElement('a');
           create.appendChild(a);
       }
   </script>

区别

1、document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
2、innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘
3、innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
4、createElement() 创建多个元素效率稍低一点点,但是结构更清晰
总结:不同浏览器下,innerHTML 效率要比 creatElement 高

  

  

 

 

  

 

  

  

  

posted @   橘子偏爱橙子  阅读(68)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示