JavaScript-DOM
节点的层次结构
- hasChildNodes() 【父元素中是否包含子节点】
dom.hasChildNodes() 总结: 1.该方法返回的是一个布尔类型的结果用来判断当前元素中是否存在子节点。 2.该方法会将元素中所有的节点都获取(包括空格,回车符,文字,标签等)
- 父节点.chiledren【父元素中的子元素】
dom.children 总结: 1.chiledren是一个属性,不是一个方法 2.该属性返回父元素中所有子元素(只包含标签),不包括空格,回车符,纯文本等 3.返回一个伪数组 4.通过dom.children.length来判断是否存在子元素
- 根据父节点获取子节点【父元素中的子节点】
dom.childNodes 总结: 1.childNodes是一个属性,不是一个方法 2.该属性将父元素中所有节点返回(包括回车,空格等特殊符号) 3.该属性将回车符看做是一个空的文本
- 获取父元素中第一个子元素
dom.firstElementChild 总结: 1.通过该属性可以将父元素中的第一个子元素获取到【标签】 2.该属性只能获取标签,无法获取文字,空格,回车符等节点
- 获取父元素中最后一个子元素
dom.lastElementChild 总结: 1.通过该属性可以将父元素中最后一个子元素获取到【标签】 2.该属性只能获取标签,无法获取文字,空格,回车符等节点
- 获取父元素中第一个节点
dom.firstChild 总结: 1.通过该属性可以将父元素中第一个节点得到 2.节点中包括文字,回车符,换行符等
- 获取父元素中最后一个节点
dom.lastChild 总结: 1.通过该属性将父元素中最后一个节点得到 2.节点中包括文字,回车符,换行符等
操作与子元素相关的方法
☞ dom.parentNode 总结: 1.通过该属性可以获取到整个父元素节点 2.包括父元素中的所有文字,回车符等节点 ☞ 通过 nodeType 获取节点类型 dom.nodeType 总结: 1.如果nodeType返回值是1,那么代表当前节点是一个标签 2.如果nodeType返回值是3,那么代表当前节点是一个文本【回车符】 3.如果nodeType返回值是2,代表标签中的一个属性 ☞ 通过 nodeName 获取节点名称 dom.nodeName 总结: 1.如果当前节点是一个标签,那么通过该属性返回该标签的名称 2.如果当前节点是一个文本,那么通过该属性返回 #text
☞ node.nextElementSibling 总结: 1.获取当前元素的下一个兄弟元素,不包括回车符,返回的是一个标签 ☞ node.nextSibling 总结: 1.获取当前元素的下一个兄弟元素,包括回车符
获取上一个节点
☞ node.previousElementSibling 总结: 1.上一个兄弟元素,不包括回车符 ☞ node.previousSibline 总结: 1.上一个兄弟元素,存在兼容性
创建元素
-
创建元素
-
document.write()
-
dom.innerHTMl
-
document.createElement()
总结: 1.createElement()只是在内存中创建了一个元素,无法再页面中显示出来 2.创建完元素后需要通过node.appendChild(子节点)将元素添加到dom树中
-
-
案例
-
创建英雄列表案例
var heads = ['姓名', '年龄', '性别', '学号', '薪资', '城市', '操作']; var datas = [ { name:'欧阳霸天',age:19,gender:'男',stuId:'1001',salary:'20000',city:'上海'}, { name:'令狐霸天',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'诸葛霸天',age:19,gender:'男',stuId:'1001',salary:'20000',city:'南京'}, { name:'西门霸天',age:19,gender:'男',stuId:'1001',salary:'20000',city:'深圳'}, { name:'鸠摩智',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'段延庆',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'段正淳',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'容子矩',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'崔绿华',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'梅超风',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'鲁有脚',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'焦木和尚',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'韩小莹',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'侯通海',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'欧阳克',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'欧阳峰',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'玄真道人',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'司徒伯雷',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'陈近南',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'张康年',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'吴大鹏',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'西奥图三世',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'任盈盈',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'林远图',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'郑镖头',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'张金鏊',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'陈歪嘴',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'洪人雄',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'余人彦',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'劳德诺',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'玉钟子',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'史镖头',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'东方不败',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'} ];
-
示例代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> table { margin: 0 auto; width: 800px; } table, td, th { border: 1px solid #ccc; border-collapse: collapse; text-align: center; } </style> </head> <body> <input type="button" value="按钮"> <script type="text/javascript"> var heads = ['姓名', '年龄', '性别', '学号', '薪资', '城市', '操作']; var datas = [ { name:'欧阳霸天',age:19,gender:'男',stuId:'1001',salary:'20000',city:'上海'}, { name:'令狐霸天',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'诸葛霸天',age:19,gender:'男',stuId:'1001',salary:'20000',city:'南京'}, { name:'西门霸天',age:19,gender:'男',stuId:'1001',salary:'20000',city:'深圳'}, { name:'鸠摩智',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'段延庆',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'段正淳',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'容子矩',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'崔绿华',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'梅超风',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'鲁有脚',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'焦木和尚',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'韩小莹',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'侯通海',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'欧阳克',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'欧阳峰',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'玄真道人',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'司徒伯雷',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'陈近南',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'张康年',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'吴大鹏',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'西奥图三世',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'任盈盈',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'林远图',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'郑镖头',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'张金鏊',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'陈歪嘴',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'洪人雄',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'余人彦',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'劳德诺',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'玉钟子',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'史镖头',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'}, { name:'东方不败',age:19,gender:'男',stuId:'1001',salary:'20000',city:'北京'} ]; var btn = document.querySelector('input'); //表示可以创建 var flag = true; btn.onclick = function() { if(flag) { //1. 先创建表格 var table = document.createElement('table'); //2. 创建第一行 var fs_tr = document.createElement('tr'); //3. 创建表头 for(var i = 0; i < heads.length; i++) { var th=document.createElement('th'); th.innerHTML=heads[i]; fs_tr.appendChild(th); } //4. 将第一行添加到表格中 table.appendChild(fs_tr); //5. 动态创建主体中的行 for(var i = 0; i < datas.length; i++) { var tr = document.createElement('tr'); //创建td for(key in datas[i]) { var td = document.createElement('td'); td.innerHTML = datas[i][key]; tr.appendChild(td); } //动态创建最后一个td var last_td = document.createElement('td'); last_td.innerHTML = '<a href="javascript:;">删除</a>'; tr.appendChild(last_td); //添加到table中 table.appendChild(tr); } //6. 将table添加到body中 document.body.appendChild(table); //给每一个a标签注册一个点击事件 var alinks = document.querySelectorAll('a'); for(var i = 0; i < alinks.length; i++) { alinks[i].onclick = function() { if(confirm('确定要删除么?')) { //隐藏元素 // this.parentNode.parentNode.style.display = 'none'; //使用父元素移除 table.removeChild(this.parentNode.parentNode); }else { alert('取消删除操作'); } } } //给每一个li注册一个鼠标进入事件和离开事件 var lis = document.querySelectorAll('tr:nth-child(n+2)'); for(var i = 0; i < lis.length; i++) { lis[i].onmouseenter = function() { this.style = 'background: #ccc; cursor: pointer;'; } lis[i].onmouseleave = function() { this.style = ''; } } //7.始终只能创建一个 flag = false; } } </script> </body> </html>
-
动态创建元素的其他方式
-
父节点.insertBefore(“新的节点”,“旧的子节点”)
注意: 1.我们通过createElement创建的元素,默认都在元素的末尾添加 2.通过insertBefore可以在父元素中某一个子元素的前面添加一个新元素
-
父节点.replaceChild(“新节点”,“旧节点”)
总结: 1.通过新节点将原来的节点替换掉
-
元素.cloneNode(true| false)
true: 代表克隆元素内部的所有信息 false: 默认值,只克隆外边的标签
输入框事件
-
oninput事件
dom.oninput = function() { } 总结: 1.用户在输入内容时候触发该事件
-
示例:
<body>
<input type="text">
<script>
var input = document.querySelector('input');
//用户输入事件
input.oninput = function() {
var v = this.value;
console.log(v.length);
}
</script>
</body>
注册事件
-
on方式注册事件
问题: 使用on的方式给标签注册事件,后面的事件会将前面的事件覆盖掉
-
addEventListener(参数1,参数2,参数3) 给元素注册事件
参数介绍: 第一个参数:代表事件类型【click,focus...】 第二个参数:事件执行函数 第三个参数:参数,可选,true或者false(默认) 备注: 1.存在浏览器兼容性IE9以后 2.多在移动端使用 语法: 事件源.addEventListener(事件类型,事件处理程序);
-
attachEvent() 给元素注册事件
dom.attachEvent('事件类型',function(){ }) 注意: 1.第一个参数:代表事件类型需要 加 on 2.该事件注册方式是给IE低版本浏览器使用的
-
移除元素事件
1.如果通过on给元素注册事件,那么移除对应的事件赋值为null即可 例如: div.onclick = null; 2.removeEventListener() 注意:如果需要通过removeEventListener移除事件,那么在使用addEventListener注册事件的时候必须是命名函数,不能是匿名函数 3. detachEvent() ,移除事件也需要命名函数
-
addEventListener()第三个参数介绍 【事件流】
事件冒泡: 如果addEventListener的第三个参数为false 事件捕获: 如果addEventListener的第三个参数为 true 总结: ☞事件发生的三个阶段: 1. 捕获阶段 2. 执行阶段: 执行当前点击的元素 3. 冒泡阶段: ☞ on 或者 attachEvent方式注册的事件,无法捕获事件以上三个阶段,只能有事件冒泡,因为不支持第三个参数
-
委托
事件委托:本质就是利用了事件冒泡 实现步骤:通过事件对象参数,来捕获当前事件相关的数据。 事件参数(对象):当事件发生的时候,可以捕获一些和当前事件相关的数据 案例:点击li获取内容信息 <body> <ul> <li>li标签1</li> <li>li标签2</li> <li>li标签3</li> <li>li标签4</li> </ul> <script> var ul = document.querySelector('ul'); ul.onclick = function (e) { console.log(e.target.innerText); } </script> </body>
-
事件对象
通过事件对象可以获取到事件发生的时候和事件相关的数据 ☞ 在标准的方式中,在事件处理程序中,通过参数 “e”事件对象获取 ☞ 在IE低版本中, 通过window.event 获取事件对象 e.target : 获取真正触发事件的对象 e.type: 事件类型 e.clientX: 相对可视区域左上角横坐标【以HTML标签为参照,如果将body8像素去掉,body和html一样】 e.clientY:相对可视区域左上角纵坐标【以HTML标签为参照,如果将body8像素去掉,body和html一样】 e.offsetX: 横坐标是相对于当前点击元素的左上角 e.offsetY: 相对当前点击元素的左上角 e.pageX: 相对整个body标签左上角【始终以整个页面最左边为参照】 e.pageY: 相对整个body标签左上角【始终以整个页面最上面为参照】 e.screenX: 相对整个浏览器的左上角 e.screenY: 相对整个浏览器的左上角 e.stopPropagation() 阻止事件冒泡 案例: 1.鼠标移动案例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> * { margin: 0; padding: 0; } .box { width: 200px; height: 200px; border: 1px solid red; } .box img { width: 100%; height: 100%; } </style> </head> <body> <div class="box"> <img src="xn.png" alt=""> </div> <script type="text/javascript"> var box = document.querySelector("div"); document.addEventListener("mousemove", function(e){ //获取鼠标移动的位置 var px = e.pageX; var py = e.pageY; //设置img的位置是当前鼠标的位置 box.style.position = "relative"; box.style.left = px+"px"; box.style.top = py+"px" }) </script> </body> </html> 2.键盘移动案例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> body { background: skyblue; } img { width: 100px; position: absolute; left: 0; top: 0; } .toLeft { transform: rotateY(180deg); } </style> </head> <body> <img src="xn.png" alt=""> <script> // 1. 获取图片元素 var img = document.querySelector('img'); // 2. 定义两个变量,分别表示小鸟的left和top var x = 0; var y = 0; // 3. 给document注册onkeydown事件 document.onkeydown = function (e) { // 3.1 通过事件对象中的keyCode属性侦测按键(四种情况) // e.keyCode 返回一个键码值,数字 if (e.keyCode == 37) { console.log('←'); // 调头 img.className = 'toLeft'; x-=10; } else if (e.keyCode == 38) { console.log('↑'); y-=10; } else if (e.keyCode == 39) { console.log('→'); // 调头 img.className = ''; x+=10; } else if (e.keyCode == 40) { console.log('↓'); y+=10; } // 把最新的值赋值图片的left和top样式 img.style.left = x + 'px'; img.style.top = y + 'px'; }; </script> </body> </html> ☞键盘事件: onkeydown: 用户按下任何键盘键(包括系统按钮,如箭头键和功能键)时发生。 onkeyup : 用户放开任何先前按下的键盘键时发生。 onkeypress: 【这个事件在用户按下并放开任何字母数字键时发生。系统按钮(例如,箭头键,TAB,ctrl等功能键)无法得到识别。 】 e.key: 获取按下键的名称 e.keyCode : 键对应的值
案例使用图片:
如有不足,请多指教,
未完待续,持续更新!
大家一起进步!