1、什么是DOM?
文档对象模型( Document Object Model ,简称DOM) ,是W3C组织推荐的处理可扩展标记语言(HTML或者XML)的标准编程接口。W3C已经定义了一系列的DOM接口,通过这些接口可以改变网页的内容、结构和样式。
DOM文档中的元素皆为对象。
2、获取元素
DOM在实际开发中主要用来操作元素。操作前先得获取元素。
获取元素的方式:
2.1 根据ID获取;
使用 getElementById() 方法可以获取带有 ID 的元素对象。
document.getElementById(‘id‘);
使用 console.dir() 可以打印我们获取的元素对象,更好的查看对象里面的属性和方法。
2.2 根据标签名获取;
使用 getElementsByTagName() 方法可以返回带有指定标签名的对象的集合。
document.getElementsByTagName(‘标签名‘);
注意:因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历。如果获取不到元素,则返回为空的伪数组(因为获取不到对象)
还可以获取某个元素(父元素)内部所有指定标签名的子元素。
element.getElementsByTagName(‘标签名‘);
注意:父元素必须是单个对象(必须指明是哪一个元素对象)。获取的时候不包括父元素自己。
2.3 通过HTML5新增的方法获取
1. document.getElementsByClassName(‘类名’);// 根据类名返回元素对象集合
2. document.querySelector(‘选择器如#btn‘); // 根据指定选择器返回第一个元素对象,.nav,#btn,input
3. document.querySelectorAll(‘选择器‘); // 根据指定选择器返回所有元素对象,伪数组
2.4 特殊元素获取
获取body元素:doucumnet.body // 返回body元素对象
获取html元素:document.documentElement // 返回html元素对象
3、事件基础
3.1 事件简介
JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为。
简单理解: 触发--- 响应机制。
网页中的每个元素都可以产生某些可以触发 JavaScript 的事件,例如,我们可以在用户点击某按钮时产生一个事件,然后去执行某些操作。
3.2 事件三要素
1. 事件源 (谁)
2. 事件类型 (什么事件)
3. 事件处理程序 (做啥)
如:点击按钮弹出对话框功能
var btn = document.getElementById(‘btn‘);
btn.onclick = function() {
alert(‘你好吗‘);
};
3.3 常见鼠标事件
onclick:鼠标点击左键触发
onmouseover:鼠标经过触发
onmouseout:鼠标离开触发
onmousedown:鼠标按下触发
onfocus:获得鼠标焦点触发;
onblur:失去鼠标焦点触发
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <button id="btn">关灯</button> 9 <script> 10 var btn = document.getElementById(‘btn‘); 11 var flag = 0; 12 btn.onclick = function() { 13 if (flag === 0) { 14 document.body.style.backgroundColor = ‘black‘; 15 this.innerHTML = ‘开灯‘; 16 flag = 1; 17 } else { 18 document.body.style.backgroundColor = ‘#fff‘; 19 this.innerHTML = ‘关灯‘; 20 flag = 0; 21 } 22 } 23 </script> 24 </body> 25 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 input{ 8 color:#333; 9 } 10 </style> 11 </head> 12 <body> 13 <div> 14 <input type="text" placeholder="手机"> 15 </div> 16 <script> 17 var text = document.querySelector(‘input‘); 18 text.onfocus = function () { 19 text.placeholder = ‘‘; 20 }; 21 text.onblur = function () { 22 text.placeholder = ‘手机‘; 23 } 24 </script> 25 </body> 26 </html>
4、操作元素
JavaScript 的 DOM 操作可以改变网页内容、结构和样式,我们可以利用 DOM 操作元素来改变元素里面的内
容 、属性等。
4.1 元素内容修改
element.innerHTML :
登录案例
起始位置到终止位置的全部内容,包括 html 标签,同时保留空格和换行。
element.innerText :
从起始位置到终止位置的内容, 但它去除 html 标签, 同时空格和换行也会去掉。
表单元素属性操作:type,value,selected,checked,disabled
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>登录</title> 6 <style> 7 .box{ 8 width:300px; 9 border-bottom:1px solid #CCCCCC; 10 position: relative; 11 margin: 100px auto; 12 } 13 .box input{ 14 width: 270px; 15 height: 30px; 16 border:0; 17 outline: none; 18 } 19 .box img{ 20 width: 24px; 21 position: absolute; 22 top:2px; 23 right:2px; 24 } 25 </style> 26 </head> 27 <body> 28 <div class="box"> 29 <label for=""> 30 <img src="images/close.png" alt=""> 31 </label> 32 <input type="password"> 33 </div> 34 <script> 35 var img = document.querySelector(‘img‘); 36 var input = document.querySelector(‘input‘); 37 img.onclick = function () { 38 if(input.type === ‘password‘){ 39 input.type = "text"; 40 img.src = "images/open.png"; 41 }else if(input.type === ‘text‘){ 42 input.type = "password"; 43 img.src = "images/close.png"; 44 } 45 46 47 } 48 </script> 49 </body> 50 </html>
4.2 样式属性修改
我们可以通过 JS 修改元素的大小、颜色、位置等样式。
1. element.style 行内样式操作
JS 修改 style 样式操作,产生的是行内样式,CSS 权重比较高。
2. element.className 类名样式操作
如果样式修改较多,可以采取操作类名方式更改元素样式。
class因为是个保留字,因此使用className来操作元素类名属性。
className 会直接更改元素的类名,会覆盖原先的类名。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 div{ 8 width: 600px; 9 margin: 100px auto; 10 } 11 .message { 12 display: inline-block; 13 font-size: 12px; 14 color: #999999; 15 background: url(images/mess.png) no-repeat ; 16 padding-left: 20px; 17 margin-left: 10px; 18 } 19 .wrong{ 20 color:red; 21 background: url(images/wrong.png) no-repeat ; 22 } 23 .right { 24 color: green; 25 background: url(images/right.png) no-repeat ; 26 } 27 </style> 28 </head> 29 <body> 30 <div class="register"> 31 <input type="text" class="ipt"> 32 <p class="message">请输入6-16位的密码</p> 33 </div> 34 <script> 35 //输入的密码长度不在6-16位之间失去焦点后展示红色提示信息,获得焦点后提示信息显示默认值 36 var div = document.querySelector(‘div‘); 37 var input = document.querySelector(‘.ipt‘); 38 var message = document.querySelector(‘.message‘); 39 input.onblur = function () { 40 if(this.value.length<6 || input.value.length>16){ 41 message.className = ‘message wrong‘; 42 message.innerHTML = ‘密码格式不正确‘; 43 }else{ 44 message.className = ‘message right‘; 45 message.innerHTML = ‘密码格式正确‘; 46 } 47 }; 48 input.onfocus = function () { 49 message.className = ‘message‘; 50 message.innerHTML = ‘请输入6-16位的密码‘; 51 52 } 53 </script> 54 </body> 55 </html>
4.3 排他思想
如果有同一组元素,我们想要某一个元素实现某种样式, 需要用到循环的排他思想算法:
1. 所有元素全部清除样式(干掉其他人)
2. 给当前元素设置样式 (留下我自己)
3. 注意顺序不能颠倒,首先干掉其他人,再设置自己
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 * { 8 margin: 0; 9 padding: 0; 10 } 11 .change{ 12 overflow: hidden; 13 margin: 100px auto; 14 width: 410px; 15 background-color: #fff; 16 padding-top: 3px; 17 } 18 li{ 19 list-style-type: none; 20 float: left; 21 margin: 0 1px; 22 } 23 li img{ 24 width: 100px; 25 } 26 </style> 27 </head> 28 <body> 29 <ul class="change"> 30 <li><img src="images/1.jpg" alt=""></li> 31 <li><img src="images/2.jpg" alt=""></li> 32 <li><img src="images/3.jpg" alt=""></li> 33 <li><img src="images/4.jpg" alt=""></li> 34 </ul> 35 <script> 36 var imgs = document.querySelector(‘.change‘).querySelectorAll(‘img‘); 37 for (var i = 0; i < imgs.length; i++) { 38 imgs[i].onclick = function () { 39 document.body.style.background = ‘url(‘+this.src+‘)‘; 40 } 41 } 42 </script> 43 44 </body> 45 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 8 <title>Document</title> 9 <style> 10 table { 11 width: 800px; 12 margin: 100px auto; 13 text-align: center; 14 border-collapse: collapse; 15 font-size: 14px; 16 } 17 18 thead tr { 19 height: 30px; 20 background-color: skyblue; 21 } 22 23 tbody tr { 24 height: 30px; 25 } 26 27 tbody td { 28 border-bottom: 1px solid #d7d7d7; 29 font-size: 12px; 30 color: blue; 31 } 32 33 .bg { 34 background-color: pink; 35 } 36 </style> 37 </head> 38 39 <body> 40 <table> 41 <thead> 42 <tr> 43 <th>代码</th> 44 <th>名称</th> 45 <th>最新公布净值</th> 46 <th>累计净值</th> 47 <th>前单位净值</th> 48 <th>净值增长率</th> 49 </tr> 50 </thead> 51 <tbody> 52 <tr> 53 <td>003526</td> 54 <td>农银金穗3个月定期开放债券</td> 55 <td>1.075</td> 56 <td>1.079</td> 57 <td>1.074</td> 58 <td>+0.047%</td> 59 </tr> 60 <tr> 61 <td>003526</td> 62 <td>农银金穗3个月定期开放债券</td> 63 <td>1.075</td> 64 <td>1.079</td> 65 <td>1.074</td> 66 <td>+0.047%</td> 67 </tr> 68 <tr> 69 <td>003526</td> 70 <td>农银金穗3个月定期开放债券</td> 71 <td>1.075</td> 72 <td>1.079</td> 73 <td>1.074</td> 74 <td>+0.047%</td> 75 </tr> 76 <tr> 77 <td>003526</td> 78 <td>农银金穗3个月定期开放债券</td> 79 <td>1.075</td> 80 <td>1.079</td> 81 <td>1.074</td> 82 <td>+0.047%</td> 83 </tr> 84 <tr> 85 <td>003526</td> 86 <td>农银金穗3个月定期开放债券</td> 87 <td>1.075</td> 88 <td>1.079</td> 89 <td>1.074</td> 90 <td>+0.047%</td> 91 </tr> 92 <tr> 93 <td>003526</td> 94 <td>农银金穗3个月定期开放债券</td> 95 <td>1.075</td> 96 <td>1.079</td> 97 <td>1.074</td> 98 <td>+0.047%</td> 99 </tr> 100 </tbody> 101 </table> 102 <script> 103 // 1.获取元素 获取的是 tbody 里面所有的行 104 var trs = document.querySelector(‘tbody‘).querySelectorAll(‘tr‘); 105 // 2. 利用循环绑定注册事件 106 for (var i = 0; i < trs.length; i++) { 107 // 3. 鼠标经过事件 onmouseover 108 trs[i].onmouseover = function() { 109 this.className = ‘bg‘; 110 }; 111 // 4. 鼠标离开事件 onmouseout 112 trs[i].onmouseout = function() { 113 this.className = ‘‘; 114 } 115 } 116 </script> 117 </body> 118 119 </html>
1 <!DOCTYPE html> 2 <html> 3 4 <head lang="en"> 5 <meta charset="UTF-8"> 6 <title></title> 7 <style> 8 * { 9 padding: 0; 10 margin: 0; 11 } 12 13 .wrap { 14 width: 300px; 15 margin: 100px auto 0; 16 } 17 18 table { 19 border-collapse: collapse; 20 border-spacing: 0; 21 border: 1px solid #c0c0c0; 22 width: 300px; 23 } 24 25 th, 26 td { 27 border: 1px solid #d0d0d0; 28 color: #404060; 29 padding: 10px; 30 } 31 32 th { 33 background-color: #09c; 34 font: bold 16px "微软雅黑"; 35 color: #fff; 36 } 37 38 td { 39 font: 14px "微软雅黑"; 40 } 41 42 tbody tr { 43 background-color: #f0f0f0; 44 } 45 46 tbody tr:hover { 47 cursor: pointer; 48 background-color: #fafafa; 49 } 50 </style> 51 52 </head> 53 54 <body> 55 <div class="wrap"> 56 <table> 57 <thead> 58 <tr> 59 <th> 60 <input type="checkbox" id="j_cbAll" /> 61 </th> 62 <th>商品</th> 63 <th>价钱</th> 64 </tr> 65 </thead> 66 <tbody id="j_tb"> 67 <tr> 68 <td> 69 <input type="checkbox" /> 70 </td> 71 <td>iPhone8</td> 72 <td>8000</td> 73 </tr> 74 <tr> 75 <td> 76 <input type="checkbox" /> 77 </td> 78 <td>iPad Pro</td> 79 <td>5000</td> 80 </tr> 81 <tr> 82 <td> 83 <input type="checkbox" /> 84 </td> 85 <td>iPad Air</td> 86 <td>2000</td> 87 </tr> 88 <tr> 89 <td> 90 <input type="checkbox" /> 91 </td> 92 <td>Apple Watch</td> 93 <td>2000</td> 94 </tr> 95 96 </tbody> 97 </table> 98 </div> 99 <script> 100 // 1. 全选和取消全选做法: 让下面所有复选框的checked属性(选中状态) 跟随 全选按钮即可 101 // 获取元素 102 var j_cbAll = document.getElementById(‘j_cbAll‘); // 全选按钮 103 var j_tbs = document.getElementById(‘j_tb‘).getElementsByTagName(‘input‘); // 下面所有的复选框 104 // 注册事件 105 j_cbAll.onclick = function() { 106 // this.checked 它可以得到当前复选框的选中状态如果是true 就是选中,如果是false 就是未选中 107 for (var i = 0; i < j_tbs.length; i++) { 108 j_tbs[i].checked = this.checked; 109 } 110 }; 111 // 2. 下面复选框需要全部选中, 上面全选才能选中做法: 给下面所有复选框绑定点击事件,每次点击,都要循环查看下面所有的复选框是否有没选中的,如果有一个没选中的, 上面全选就不选中。 112 for (var i = 0; i < j_tbs.length; i++) { 113 j_tbs[i].onclick = function() { 114 // flag 控制全选按钮是否选中 115 var flag = true; 116 // 每次点击下面的复选框都要循环检查者4个小按钮是否全被选中 117 for (var i = 0; i < j_tbs.length; i++) { 118 if (!j_tbs[i].checked) { 119 flag = false; 120 break; // 退出for循环 这样可以提高执行效率 因为只要有一个没有选中,剩下的就无需循环判断了 121 } 122 } 123 j_cbAll.checked = flag; 124 } 125 } 126 </script> 127 </body> 128 129 </html>
4.4 自定义属性操作
获取属性
1 、element.属性名
获取内置属性值(元素本身自带的属性)
2、element.getAttribute(‘属性名‘);
主要获得自定义的属性 (标准)
设置属性值
element.属性 = ‘值’ 设置内置属性值。
element.setAttribute(‘属性‘, ‘值‘);
移除属性
element.属性=‘ ‘
element.removeAttribute(‘属性‘);
4.5 自定义属性
自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。
自定义属性获取是通过getAttribute(‘属性’) 获取。
但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。
H5给我们新增了自定义属性:
设置H5自定义属性
H5规定自定义属性data-开头做为属性名并且赋值。比如 <div data-index=“1”></div>
或者使用 JS 设置,element.setAttribute(‘data-index’, 2)
获取H5自定义属性
1. 兼容性获取 element.getAttribute(‘data-index’);
2. H5新增 element.dataset.index 或者 element.dataset[‘index’] ie 11才开始支持
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 *{ 8 margin: 0; 9 padding: 0; 10 } 11 .tab{ 12 width: 500px; 13 margin: 200px auto; 14 } 15 .tab-list li{ 16 float: left; 17 width: 125px; 18 height: 50px; 19 line-height: 50px; 20 text-align: center; 21 cursor: pointer; 22 } 23 .current{ 24 background-color: pink; 25 } 26 .tab-content{ 27 margin-top: 30px; 28 } 29 li{ 30 list-style-type: none; 31 } 32 .item{ 33 padding-top: 20px; 34 display:none; 35 } 36 </style> 37 </head> 38 <body> 39 <div class="tab"> 40 <div class="tab-list"> 41 <ul> 42 <li class="current" >华为</li> 43 <li >小米</li> 44 <li >苹果</li> 45 <li >三星</li> 46 </ul> 47 </div> 48 <div class="tab-content"> 49 <div class="item" style="display: block;">这是华为手机</div> 50 <div class="item" >这是小米手机</div> 51 <div class="item" >这是苹果手机</div> 52 <div class="item" >这是三星手机</div> 53 </div> 54 <script> 55 //要求点击上面的手机类后背景色变粉,下面也显示相对应的手机信息。 56 //变色可用排他循环思想处理;下面映射关系的改变,可以在上下都添加一个自定义属性, 57 //其属性值一一对应,点击后获得上面的属性值,在下面遍历获得各自属性值,若下面属性值有与上面 58 //相等的,就将下面div样式中的display改为block,不等改为none即可。 59 60 var lists = document.querySelector(‘.tab-list‘).querySelectorAll(‘li‘); 61 var items = document.querySelectorAll(‘.item‘); 62 for (var i = 0; i < lists.length; i++) { 63 lists[i].setAttribute(‘data-index‘,i); 64 lists[i].onclick = function () { 65 for (var i = 0; i < lists.length; i++) { 66 lists[i].className = ‘‘; 67 } 68 this.className = ‘current‘; 69 var index = this.getAttribute(‘data-index‘); 70 for (var j = 0; j < items.length; j++) { 71 items[j].setAttribute(‘data-index‘, j); 72 if (items[j].getAttribute(‘data-index‘) === index) { 73 items[j].style.display = ‘block‘; 74 } else { 75 items[j].style.display = ‘none‘ 76 } 77 } 78 } 79 } 80 </script> 81 82 </div> 83 </body> 84 </html>
内地阿飞飞发if你发奶奶
5、节点操作
利用DOM提供的方法获取元素逻辑性不强,并且很繁琐,如 document.getElementsByTagName()
利用父子兄节点层级关系获取元素则逻辑性更强,也更简单些。
5.1 节点概述
网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。
HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。
一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
元素节点 nodeType 为 1
属性节点 nodeType 为 2
文本节点 nodeType 为 3 (文本节点包含文字、空格、换行等)
在实际开发中,节点操作主要操作的是元素节点。
5.2 节点层级
利用 DOM 树可以把节点划分为不同的层级关系,常见的是父子兄层级关系。
父级节点
node.parentNode
parentNode 属性可返回某节点的父节点,注意是最近的一个父节点;
如果指定的节点没有父节点则返回 null;
子节点
1. parentNode.childNodes(标准)
parentNode.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合。
注意:返回值里面包含了所有的子节点,包括元素节点,文本节点等。
如果只想要获得里面的元素节点,则需要专门处理。 所以我们一般不提倡使用childNodes
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]);
}
}
2. parentNode.children(非标准)
parentNode.children 是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回 (这个是我们重点掌握的)。
虽然children 是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用。
3. parentNode.firstChild
firstChild 返回第一个子节点,找不到则返回null。同样,也是包含所有的节点。
4. parentNode.lastChild
lastChild 返回最后一个子节点,找不到则返回null。同样,也是包含所有的节点。
5. parentNode.firstElementChild
firstElementChild 返回第一个子元素节点,找不到则返回null。
6. parentNode.lastElementChild
lastElementChild 返回最后一个子元素节点,找不到则返回null。
注意:这两个方法有兼容性问题,IE9 以上才支持。
实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便,而 firstElementChild 和
lastElementChild 又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?
解决方案:
1. 如果想要第一个子元素节点,可以使用 parentNode.chilren[0]
2. 如果想要最后一个子元素节点,可以使用 parentNode.chilren[parentNode.chilren.length - 1]
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 * { 8 margin: 0; 9 padding: 0; 10 } 11 12 li { 13 list-style-type: none; 14 } 15 16 a { 17 text-decoration: none; 18 font-size: 14px; 19 } 20 21 .nav { 22 margin: 100px; 23 } 24 25 .nav>li { 26 position: relative; 27 float: left; 28 width: 80px; 29 height: 41px; 30 text-align: center; 31 } 32 33 .nav li a { 34 display: block; 35 width: 100%; 36 height: 100%; 37 line-height: 41px; 38 color: #333; 39 } 40 41 .nav>li>a:hover { 42 background-color: #eee; 43 } 44 45 .nav ul { 46 display: none; 47 position: absolute; 48 top: 41px; 49 left: 0; 50 width: 100%; 51 border-left: 1px solid #FECC5B; 52 border-right: 1px solid #FECC5B; 53 } 54 55 .nav ul li { 56 border-bottom: 1px solid #FECC5B; 57 } 58 59 .nav ul li a:hover { 60 background-color: #FFF5DA; 61 } 62 </style> 63 </head> 64 65 <body> 66 <ul class="nav"> 67 <li> 68 <a href="#">视频</a> 69 <ul> 70 <li> 71 <a href="">电影</a> 72 </li> 73 <li> 74 <a href="">电视剧</a> 75 </li> 76 <li> 77 <a href="">动画片</a> 78 </li> 79 </ul> 80 </li> 81 <li> 82 <a href="#">图片</a> 83 <ul> 84 <li> 85 <a href="">风景</a> 86 </li> 87 <li> 88 <a href="">唯美</a> 89 </li> 90 <li> 91 <a href="">人物</a> 92 </li> 93 <li> 94 <a href="">小清新</a> 95 </li> 96 </ul> 97 </li> 98 <li> 99 <a href="#">文章</a> 100 <ul> 101 <li> 102 <a href="">散文</a> 103 </li> 104 <li> 105 <a href="">小说</a> 106 </li> 107 <li> 108 <a href="">诗歌</a> 109 </li> 110 </ul> 111 </li> 112 <li> 113 <a href="#">其他</a> 114 <ul> 115 <li> 116 <a href="">联系</a> 117 </li> 118 <li> 119 <a href="">关于</a> 120 </li> 121 <li> 122 <a href="">商业合作</a> 123 </li> 124 </ul> 125 </li> 126 </ul> 127 <script> 128 // 1. 获取元素 129 var nav = document.querySelector(‘.nav‘); 130 var lis = nav.children; // 得到4个小li 131 // 2.循环注册事件 132 for (var i = 0; i < lis.length; i++) { 133 lis[i].onmouseover = function() { 134 this.children[1].style.display = ‘block‘; 135 }; 136 lis[i].onmouseout = function() { 137 this.children[1].style.display = ‘none‘; 138 } 139 } 140 </script> 141 </body> 142 143 </html>
兄弟节点
1. node.nextSibling
nextSibling 返回当前元素的下一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。
2. node.previousSibling
previousSibling 返回当前元素上一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。
3. node.nextElementSibling
nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回null。
4. node.previousElementSibling
previousElementSibling 返回当前元素上一个兄弟节点,找不到则返回null。
注意:这两个方法有兼容性问题, IE9 以上才支持。
如何解决兼容性问题 ?
自己封装一个兼容性的函数。
function getNextElementSibling(element) {
var el = element;
while (el = el.nextSibling) {
if (el.nodeType === 1) { //注意这里的条件的写法,是一个赋值语句
return el;
}
}
return null;
}
5.3 创建节点
document.createElement(‘tagName‘)
document.createElement() 方法创建由 tagName 指定的 HTML 元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点。
5.4 添加节点
1. node.appendChild(child)
node.appendChild() 方法将一个节点添加到指定父节点的子节点列表末尾。类似于 CSS 里面的after 伪元素。
2. node.insertBefore(child, 指定元素)
node.insertBefore() 方法将一个节点添加到父节点的指定子节点前面。类似于 CSS 里面的 before伪元素。
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Document</title> 7 <style> 8 * { 9 margin: 0; 10 padding: 0; 11 } 12 13 body { 14 padding: 100px; 15 } 16 17 textarea { 18 width: 200px; 19 height: 100px; 20 border: 1px solid pink; 21 outline: none; 22 resize: none; 23 } 24 25 ul { 26 margin-top: 50px; 27 } 28 29 li { 30 width: 300px; 31 padding: 5px; 32 background-color: rgb(245, 209, 243); 33 color: red; 34 font-size: 14px; 35 margin: 15px 0; 36 } 37 </style> 38 </head> 39 40 <body> 41 <textarea name="" id=""></textarea> 42 <button>发布</button> 43 <ul> 44 45 </ul> 46 <script> 47 // 1. 获取元素 48 var btn = document.querySelector(‘button‘); 49 var text = document.querySelector(‘textarea‘); 50 var ul = document.querySelector(‘ul‘); 51 // 2. 注册事件 52 btn.onclick = function() { 53 if (text.value === ‘‘) { 54 alert(‘您没有输入内容‘); 55 return false; 56 } else { 57 // console.log(text.value); 58 // (1) 创建元素 59 var li = document.createElement(‘li‘); 60 // 先有li 才能赋值 61 li.innerHTML = text.value; 62 // (2) 添加元素 63 // ul.appendChild(li); 64 ul.insertBefore(li, ul.children[0]); 65 } 66 } 67 </script> 68 </body> 69 70 </html>
5.5 删除节点
node.removeChild(child)
node.removeChild() 方法从 DOM 中删除一个子节点,返回删除的节点。
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Document</title> 7 </head> 8 <body> 9 <button>删除</button> 10 <ul> 11 <li>熊大</li> 12 <li>熊二</li> 13 <li>光头强</li> 14 </ul> 15 <script> 16 // 1.获取元素 17 var ul = document.querySelector(‘ul‘); 18 var btn = document.querySelector(‘button‘); 19 // 2. 删除元素 node.removeChild(child) 20 // ul.removeChild(ul.children[0]); 21 // 3. 点击按钮依次删除里面的孩子 22 btn.onclick = function() { 23 if (ul.children.length == 0) { 24 this.disabled = true; 25 } else { 26 ul.removeChild(ul.children[0]); 27 } 28 } 29 </script> 30 </body> 31 32 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Document</title> 7 <style> 8 * { 9 margin: 0; 10 padding: 0; 11 } 12 body { 13 padding: 100px; 14 } 15 textarea { 16 width: 200px; 17 height: 100px; 18 border: 1px solid pink; 19 outline: none; 20 resize: none; 21 } 22 ul { 23 margin-top: 50px; 24 } 25 li { 26 width: 300px; 27 padding: 5px; 28 background-color: rgb(245, 209, 243); 29 color: red; 30 font-size: 14px; 31 margin: 15px 0; 32 } 33 li a { 34 float: right; 35 } 36 </style> 37 </head> 38 39 <body> 40 <textarea name="" id=""></textarea> 41 <button>发布</button> 42 <ul> 43 44 </ul> 45 <script> 46 // 1. 获取元素 47 var btn = document.querySelector(‘button‘); 48 var text = document.querySelector(‘textarea‘); 49 var ul = document.querySelector(‘ul‘); 50 // 2. 注册事件 51 btn.onclick = function() { 52 if (text.value == ‘‘) { 53 alert(‘您没有输入内容‘); 54 return false; 55 } else { 56 // console.log(text.value); 57 // (1) 创建元素 58 var li = document.createElement(‘li‘); 59 // 先有li 才能赋值 60 li.innerHTML = text.value + "<a href=‘javascript:;‘>删除</a>"; 61 // (2) 添加元素 62 // ul.appendChild(li); 63 ul.insertBefore(li, ul.children[0]); 64 // (3) 删除元素 删除的是当前链接的li 它的父亲 65 var as = document.querySelectorAll(‘a‘); 66 for (var i = 0; i < as.length; i++) { 67 as[i].onclick = function() { 68 // node.removeChild(child); 删除的是 li 当前a所在的li this.parentNode; 69 ul.removeChild(this.parentNode); 70 } 71 } 72 } 73 } 74 </script> 75 </body> 76 77 </html>
5.6 复制节点
node.cloneNode() 方法返回调用该方法的节点的一个副本。 也称为克隆节点/拷贝节点
注意:
1. 如果括号参数为空或者为 false ,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点。
2. 如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <ul> 9 <li>雯雯</li> 10 <li>菲菲</li> 11 <li>颖颖</li> 12 </ul> 13 <script> 14 var ul = document.querySelector(‘ul‘); 15 //var li = ul.children[0].cloneNode();//括号里为空或者false,则是浅拷贝,只复制标签 16 var li = ul.children[0].cloneNode(true);//括号里为true,则是深拷贝 17 ul.appendChild(li); 18 </script> 19 </body> 20 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Document</title> 7 <style> 8 table { 9 width: 500px; 10 margin: 100px auto; 11 border-collapse: collapse; 12 text-align: center; 13 } 14 td, 15 th { 16 border: 1px solid #333; 17 } 18 19 thead tr { 20 height: 40px; 21 background-color: #ccc; 22 } 23 </style> 24 </head> 25 26 <body> 27 <table cellspacing="0"> 28 <thead> 29 <tr> 30 <th>姓名</th> 31 <th>科目</th> 32 <th>成绩</th> 33 <th>操作</th> 34 </tr> 35 </thead> 36 <tbody> 37 38 </tbody> 39 </table> 40 <script> 41 // 1.先去准备好学生的数据 42 var datas = [{ 43 name: ‘魏璎珞‘, 44 subject: ‘JavaScript‘, 45 score: 100 46 }, { 47 name: ‘弘历‘, 48 subject: ‘JavaScript‘, 49 score: 98 50 }, { 51 name: ‘傅恒‘, 52 subject: ‘JavaScript‘, 53 score: 99 54 }, { 55 name: ‘明玉‘, 56 subject: ‘JavaScript‘, 57 score: 88 58 }, { 59 name: ‘大猪蹄子‘, 60 subject: ‘JavaScript‘, 61 score: 0 62 }]; 63 // 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行 64 var tbody = document.querySelector(‘tbody‘); 65 for (var i = 0; i < datas.length; i++) { // 外面的for循环管行 tr 66 // 1. 创建 tr行 67 var tr = document.createElement(‘tr‘); 68 tbody.appendChild(tr); 69 // 2. 行里面创建单元格(跟数据有关系的3个单元格) td 单元格的数量取决于每个对象里面的属性个数 for循环遍历对象 datas[i] 70 for (var k in datas[i]) { // 里面的for循环管列 td 71 // 创建单元格 72 var td = document.createElement(‘td‘); 73 // 把对象里面的属性值 datas[i][k] 给 td 74 // console.log(datas[i][k]); 75 td.innerHTML = datas[i][k]; 76 tr.appendChild(td); 77 } 78 // 3. 创建有删除2个字的单元格 79 var td = document.createElement(‘td‘); 80 td.innerHTML = ‘<a href="javascript:;">删除 </a>‘; 81 tr.appendChild(td); 82 } 83 // 4. 删除操作 开始 84 var as = document.querySelectorAll(‘a‘); 85 for (var i = 0; i < as.length; i++) { 86 as[i].onclick = function() { 87 // 点击a 删除 当前a 所在的行(链接的爸爸的爸爸) node.removeChild(child) 88 tbody.removeChild(this.parentNode.parentNode) 89 } 90 } 91 // for(var k in obj) { 92 // k 得到的是属性名 93 // obj[k] 得到是属性值 94 // } 95 </script> 96 </body> 97 98 </html>
5.7 三种动态创建元素方式的区别
区别:
1. document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘。弃之。
2. innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘。
3. innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂。
采取字符串拼接则由于字符串不可变,每次拼接都会向系统申请新内存空间存储写入数据导致耗时较长,而数组可变,用数组则耗时很短。比createElement()的耗时还短如果数据量大的话。
4. createElement() 创建多个元素效率稍低一点点,但是结构更清晰。
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Document</title> 7 </head> 8 9 <body> 10 <button>点击</button> 11 <p>abc</p> 12 <div class="inner"></div> 13 <div class="create"></div> 14 <script> 15 // window.onload = function() { 16 // document.write(‘<div>123</div>‘); 17 18 // } 19 // 三种创建元素方式区别 20 // 1. document.write() 创建元素 如果页面文档流加载完毕,再调用这句话会导致页面重绘 21 // var btn = document.querySelector(‘button‘); 22 // btn.onclick = function() { 23 // document.write(‘<div>123</div>‘); 24 // } 25 26 // 2. innerHTML 创建元素 27 var inner = document.querySelector(‘.inner‘); 28 // for (var i = 0; i <= 100; i++) { 29 // inner.innerHTML += ‘<a href="#">百度</a>‘ //字符串拼接耗时长 30 // } 31 var arr = []; 32 for (var i = 0; i <= 100; i++) { 33 arr.push(‘<a href="#">百度</a>‘); 34 } 35 inner.innerHTML = arr.join(‘‘); 36 // 3. document.createElement() 创建元素 37 var create = document.querySelector(‘.create‘); 38 for (var i = 0; i <= 100; i++) { 39 var a = document.createElement(‘a‘); 40 create.appendChild(a); 41 } 42 </script> 43 </body> 44 45 </html>