https://www.cnblogs.com/haiyan123/p/7598320.html
一、什么是HTML DOM
- HTML Document Object Model(文档对象模型)
- HTML DOM 定义了访问和操作HTML文档的标准方法
- HTML DOM 把 HTML 文档呈现为带有元素、属性和文本的树结构(节点树)
二、DOM树
画dom树是为了展示文档中各个对象之间的关系,用于对象的导航。
三、DOM节点
1.节点类型
HTML 文档中的每个成分都是一个节点。
DOM 是这样规定的:
整个文档是一个文档节点
每个 HTML 标签是一个元素节点
包含在 HTML 元素中的文本是文本节点
每一个 HTML 属性是一个属性节点
其中,document与element节点是重点。
2.节点关系
节点树中的节点彼此拥有层级关系。
父(parent),子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。
- 在节点树中,顶端节点被称为根(root)
- 每个节点都有父节点、除了根(它没有父节点)
- 一个节点可拥有任意数量的孩子
- 同胞是拥有相同父节点的节点
下面的图片展示了节点树的一部分,以及节点之间的关系:
3.节点查找
有两种方式:
方式一:直接查找节点(这是一个查找方法)
/ 节点查找(节点也就是一个个的标签)
document.getElementById('idname');//按照id查找,拿到的是一个标签对象
document.getElementsByClassName('classname');//按照class标签去找,得到的是一个数组里存放的标签
document.getElementsByTagName('tagname');//通过标签名去找,拿到的也是一个数组
var a = document.getElementsByName('yuan'); //按照name属性去找,拿到的也是一个数组
console.log(a);
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// / ==2.========================
var ele = document.getElementById('div1');
console.log(ele.length);//返回undified
var ele2 = document.getElementById('div3');
console.log(ele2.length);//返回undified
var ele3 = document.getElementsByClassName('div2');
console.log(ele3.length); //返回1
var ele4 = document.getElementsByTagName('p');
console.log(ele4.length) ;//返回1
var ele5 = document.getElementsByName('haiyan');
console.log(ele5.length); //返回1
//====3.=============================
id和name的不支持
var div1=document.getElementById("div1");
////支持;
var ele= div1.getElementsByTagName("p");
alert(ele.length);
////支持
var ele2=div1.getElementsByClassName("div2");
alert(ele2.length);
////不支持
var ele3=div1.getElementById("div3");
alert(ele3.length);
////不支持
var ele4=div1.getElementsByName("yuan");
alert(ele4.length)
上述的length:返回的是标签的个数,,一个是在局部下的,,,一个是在全局下的(document.~~~)
方式二:导航查找节点:通过某一个标签的位置去查找另一个标签(这是一个导航属性)
'''
parentElement // 父节点标签元素
children // 所有子标签
firstElementChild // 第一个子标签元素
lastElementChild // 最后一个子标签元素
nextElementtSibling // 下一个兄弟标签元素
previousElementSibling // 上一个兄弟标签元素
'''
// 方式二:导航查找 //<div id ='div1'> // <div class="div2" name = 'haiyan'>lallala</div> // <div name="haiyan">lkkaakkka</div> // <div id ='div3'>aaaaaaaaaaaaaa</div> // <p>hrllo</p> //</div> //注意:1.如果是数组的话后面切记getElementsByClassName('div2')[0] // 2.查找元素的那些方法Elements加了s的打印的就是数组 // 1,================== var ele = document.getElementsByClassName('div2')[0]; var ele1= ele.parentElement; console.log(ele1) ;//找div2标签的父亲 // 2.=============== var ele = document.getElementById('div1'); var ele1 = ele.children; console.log(ele1) ; //找到div1下的所有的子标签 // 3.=================== var ele = document.getElementById('div1'); var ele1 = ele.firstElementChild; console.log(ele1); //找到div1下的第一个子标签的元素 // 4.================== var ele = document.getElementById('div1'); var ele1 = ele.lastElementChild; console.log(ele1); //找到div1下的最后一个子标签的元素 // 5.=============== var ele = document.getElementsByName('haiyan')[0]; var ele1 = ele.nextElementSibling; console.log(ele1) ; //下一个兄弟标签元素 // 6.=============== var ele = document.getElementsByName('haiyan')[0]; var ele1 = ele.previousElementSibling; console.log(ele1) //上一个兄弟标签元素
四、DOM Event(事件)
1.事件类型
onclick 当用户点击某个对象时调用的事件句柄。
ondblclick 当用户双击某个对象时调用的事件句柄。
onfocus 元素获得焦点。 练习:输入框
onblur 元素失去焦点。 应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证.
onchange 域的内容被改变。 应用场景:通常用于表单元素,当元素内容被改变时触发.(三级联动)
onkeydown 某个键盘按键被按下。 应用场景: 当用户在最后一个输入框按下回车按键时,表单提交.
onkeypress 某个键盘按键被按下并松开。
onkeyup 某个键盘按键被松开。
onload 一张页面或一幅图像完成加载。
onmousedown 鼠标按钮被按下。
onmousemove 鼠标被移动。
onmouseout 鼠标从某元素移开。
onmouseover 鼠标移到某元素之上。
onmouseleave 鼠标从元素离开
onselect 文本被选中。
onsubmit 确认按钮被点击
2.绑定事件方式
方式一
<!--绑定事件的方式一--> <div onclick="foo(this)">div</div> <div class="c1">div2</div> <script> function foo(self) { console.log(self); //<div onclick="foo(this)" style="color: red;"> self.style.color = 'red'; }
//方式二
// 事件的绑定方式2:标签对象.on事件 = function (){}
var ele=document.getElementsByClassName("c1")[0];
ele.onclick=function () {
console.log(this); // this 代指: 当前触发时间的标签对象;
this.style.fontSize="30px"
};
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <input type="text" id="search" value="请输入用户名" onclick="func1()" onblur="func2()"> <script> var ele = document.getElementById("search"); function func1() { if (ele.value == "请输入用户名"){ ele.value = ""; } } function func2() { if (!ele.value.trim()){ ele.value="请输入用户名"; } } </script> </body> </html>
onload事件
onload 属性开发中 只给 body元素加.这个属性的触发 标志着 页面内容被加载完成.应用场景: 当有些事情我们希望页面加载完立刻执行,那么可以使用该事件属性.
什么时候加载完什么时候触发(如果你想把script放在body上面去,就用到onload事件了)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script> function func1() { var ele = document.getElementsByClassName("div1")[0]; alert(ele.innerHTML); } </script> </head> <body onload="func1()"> <div class="div1">hello div</div> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>节点操作</title> <style> .c1 { width: 300px; height: 200px; border: 1px solid red; } </style> <script> //如果要把script写在body的上面就可以用onload事件 //onload什么时候加载完什么时候触发这个事件 window.onload = function () { var ele_add = document.getElementsByClassName('addBtn')[0]; var ele_del = document.getElementsByClassName('delBtn')[0]; var ele_repleace = document.getElementsByClassName('replaceBtn')[0]; console.log(ele_add); //绑定的添加节点的事件 ele_add.onclick = function () { //先创建一个标签 var ele_a = document.createElement('a'); console.log(ele_a); //<a></a> ele_a.innerHTML = '点击'; //<a>点击</a> ele_a.href = 'http://www.baidu.com'; //<a href='http://www.baidu.com'>点击</a> //先创建一个标签 var ele_img = document.createElement('img'); ele_img.src = '1.png'; ele_img.width = 50; ele_img.height = 50; //找到父标签 var ele_parent = document.getElementsByClassName('c1')[0]; //然后添加 ele_parent.appendChild(ele_a); ele_parent.appendChild(ele_img); }; //绑定的删除节点的事件 ele_del.onclick = function () { //先获取要删除的元素 var ele_p = document.getElementById('p1'); //获取它的父元素 var ele_parent = document.getElementsByClassName('c1')[0]; //然后删除(注意是父元素删除子元素) ele_parent.removeChild(ele_p) }; //绑定的替换节点的事件 ele_repleace.onclick = function () { //找被替换的标签(旧标签) var ele_p = document.getElementById('p2'); //创建一个替换后的标签(新标签) var ele_img = document.createElement('img'); ele_img.src = '2.png'; ele_img.width = 100; ele_img.height = 50; //找到父节点 var ele_parent = document.getElementsByClassName('c1')[0]; //做替换(父节点替换子节点中的某一个节点):相当于一次删除加一次添加 ele_parent.replaceChild(ele_img, ele_p); }; //表格绑定删除节点的事件 var ele_dels = document.getElementsByClassName('delbtn'); for (var i = 0; i < ele_dels.length; i++) { ele_dels[i].onclick = function () { //获取删除的元素 var ele_tr = this.parentElement.parentElement; // console.log(ele_tr) //找到父节点 var ele_tbody_parent = document.getElementById('t1'); //然后删除 ele_tbody_parent.removeChild(ele_tr) } } } </script> </head> <body> <div class="c1"> <p id="p1">年后</p> <p id="p2">hello</p> </div> <button class="addBtn">ADD</button> <button class="delBtn">DEL</button> <button class="replaceBtn">Replace</button> <ul> <li>创建节点:var ele_a = document.createElement('a');</li> <li>添加节点:ele_parent.appendChild(ele_img);</li> <li>删除节点:ele_parent.removeChild(ele_p);</li> <li>替换节点:ele_parent.replaceChild(新标签,旧标签);</li> </ul> <table border="1"> <tbody id="t1"> <tr> <td><input type="checkbox"></td> <td><input type="text"></td> <td> <button class="delbtn">del1</button> </td> </tr> <tr> <td><input type="checkbox"></td> <td><input type="text"></td> <td> <button class="delbtn">del2</button> </td> </tr> <tr> <td><input type="checkbox"></td> <td><input type="text"></td> <td> <button class="delbtn">del3</button> </td> </tr> <tr> <td><input type="checkbox"></td> <td><input type="text"></td> <td> <button class="delbtn">del4</button> </td> </tr> </tbody> </table> </body> </html>
onclick
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div class="div1">hello div1</div> <div class="div1">hello div2</div> <div class="div1">hello div3</div> <div class="div1">hello div4</div> <div class="div1">hello div5</div> <p id="pp">hhhhhhhhhhhh</p> <p id="hh" onclick="func(this)">hhhhhhhhhhhh</p> <script> function func(para) {
para.style.color = "red"; console.log(para); // <p id="hh" onclick="func(this)">hhhhhhhhhhhh</p> console.log(para.previousElementSibling);// <p id="pp">hhhhhhhhhhhh</p> } var ele1 = document.getElementById("pp"); ele1.onclick=function () { alert(123); } var ele2 = document.getElementsByClassName("div1"); for (var i = 0; i < ele2.length; ++i){ ele2[i].onclick=function () { alert(ele2.length); } } </script> </body> </html>
onkeydown事件
Event 对象:Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,函数不会在事件发生前被执行!event对象在事件发生时系统已经创建好了,并且会在事件函数被调用时传给事件函数.我们获得仅仅需要接收一下即可.比如onkeydown,我们想知道哪个键被按下了,需要问下event对象的属性,这里就时KeyCode.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <input type="text" class="test"> <input type="text" id="t1"/> <script> //测试event对象 var ele = document.getElementsByClassName('test')[0]; // event :每次触发事件时所有的状态信息 // event.keyCode :保存着所有的状态信息 ele.onkeydown =function (event) { // onkeydown按下键盘触发的事件 console.log(event); console.log(event.keyCode); if (event.keyCode==13){ //按回车就会弹出 alert(666) } } </script> <script type="text/javascript"> var ele=document.getElementById("t1"); ele.onkeydown=function(e){ e=e||window.event; var keynum=e.keyCode; var keychar=String.fromCharCode(keynum); // console.log(keynum); //每次键盘敲下的状态信息 // console.log(keychar); //输入的字符 // alert(keynum); // alert(keychar) //你键盘输入的字符 }; </script> </body> </html>
onsubmit事件
当表单在提交时触发. 该属性也只能给form元素使用.应用场景: 在表单提交前验证用户输入是否正确.如果验证失败.在该方法中我们应该阻止表单的提交.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>onsubmit事件</title> <!--onsubmit事件:确定按钮被点击--> <!--在表单提交前验证用户输入是否正确.如果验证失败.在该方法中我们应该阻止表单的提交.--> <!--提交按钮本身就有一个默认事件(你点击提交的时候就会把数据发过去)--> </head> <body> <form action="" id="submit"> <p>姓名:<input type="text" class="name"></p> <p>年龄:<input type="text" class="age"></p> <input type="submit"> </form> <input type="text" class="test"> <script> var ele_form = document.getElementById('submit'); var ele_name = document.getElementsByClassName('name')[0]; var ele_age = document.getElementsByClassName('age')[0]; ele_form.onsubmit = function (event) { var username = ele_name.value; var age = ele_age.value; alert(username); alert(age); if (username=='xxxx'){ //阻止默认事件的两种方式 // 方式一: // return false; // 方式二 // 给函数给一个形参,这个形参写什么都行,一般我们写成event event.preventDefault() //阻止默认事件(表单的提交) } } </script> <script> //测试event对象 var ele = document.getElementsByClassName('test')[0]; // event :每次触发事件时所有的状态信息 // event.keyCode :保存着所有的状态信息 ele.onkeydown =function (event) { // onkeydown按下键盘触发的事件 console.log(event); console.log(event.keyCode); if (event.keyCode==13){ //按回车就会弹出 alert(666) } } </script> </body> </html>
事件传播
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件传播</title> <style> .box1 { width: 300px; height: 300px; background-color: rebeccapurple; } .box2{ width: 150px; height: 150px; background-color: yellow; } </style> </head> <body> <div class="box1"> <div class="box2"></div> </div> <script> //因为盒子1是盒子2的父亲,所以当给父亲绑定一个事件,给儿子也绑定一个事件,就像 // 继承一样,儿子会继承父亲的事件,所以现在运行的时候如果点击盒子2,会把自己的是事件和 // 父亲的事件都执行了。所以如果只想让儿子执行自己的事件,那么就得阻止发生事件传播 var ele1 = document.getElementsByClassName('box1')[0]; var ele2 = document.getElementsByClassName('box2')[0]; ele1.onclick = function () { alert(123) }; ele2.onclick = function (event) { alert(456); console.log(event); console.log(event.keyCode); // 阻止事件传播的方式 event.stopPropagation(); }; </script> </body> </html>
onchange事件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>onmouse事件</title> <style> .box{ width: 300%; height: 200px; } .title{ background: steelblue; line-height: 40px; } .con{ background: slategray; line-height: 30px; } .hide{ display: none; } </style> </head> <body> <div class="box"> <div class="title">onmouse</div> <div class="con hide"> <div><a href="" class="item">你好吗?</a></div> <div><a href="" class="item">我好啊</a></div> <div><a href="" class="item">好就好呗</a></div> </div> </div> <script> var ele_title = document.getElementsByClassName('title')[0]; var ele_box = document.getElementsByClassName('box')[0]; //鼠标指上去的事件 ele_title.onmouseover = function () { this.nextElementSibling.classList.remove('hide'); }; //鼠标移走的事件的两种方式 // 方式一(推荐) ele_box.onmouseleave= function () { ele_title.nextElementSibling.classList.add('hide'); }; // 方式二 // ele_title.onmouseout = function () { // this.nextElementSibling.classList.add('hide'); // } // 方式一和方式二的区别: // 不同点 // onmouseout:不论鼠标指针离开被选元素还是任何子元素,都会触发onmouseout事件 // onmouseleave:只有在鼠标指针离开被选元素时,才会触发onmouseleave事件 // 相同点:都是鼠标移走触发事件 </script> </body> </html>
事件委派
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件委派(委派给所有的子元素)</title> </head> <body> <ul> <li>111</li> <li>222</li> <li>333</li> </ul> <button class="addbtn">点我添加</button> </body> <script> var ele_btn = document.getElementsByClassName('addbtn')[0]; var ele_ul = document.getElementsByTagName('ul')[0]; var ele_li =document.getElementsByTagName('li'); //绑定事件 for (var i=0;i<ele_li.length;i++){ ele_li[i].onclick = function () { alert(this.innerHTML) } } //事件委派 ele_btn.onclick = function () { //创建一个li标签 var ele_li = document.createElement('li'); // ele_li.innerHTML= 444; ele_li.innerText = Math.round(Math.random()*1000); ele_ul.appendChild(ele_li);//吧创建的li标签添加到ul标签 ele_ul.addEventListener('click',function (e) { console.log(e.target); //当前点击的标签 console.log(e.target.tagName);//拿到标签的名字 LI if (e.target.tagName=='LI'){ console.log('ok'); // alert(ele_li.innerHTML) } }) } </script> </html>