JavaScript中的DOM
DOM(Document Object Model)即文档对象模型,是针对HTML 和XML 文档的一个API(应用程序编程接口)。DOM描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。
节点层次
DOM 可以将任何HTML或XML文档描绘成一个由多层节点构成的结构;文档节点是每个文档的根节点,文档节点只有一个子节点,即<html>元素称之为文档元素;文档元素是文档的最外层元素,文档中的其他所有元素都包含在文档元素中。每个文档只能有一个文档元素。
Node类型
JavaScript 中的所有节点类型都继承自Node 类型,因此所有节点类型都共享着相同的基本属性和方法。
nodeType, 用于表明节点的类型,1代表元素节点;
nodeName, 返回当前节点的name;
nodeValue, 返回或者设置当前节点的值;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//假设html文档中有这样一个p元素<p id="p">hello world!</p> var p = document.getElementById("p"); console.log(p.nodeType); //1 console.log(p.nodeName); //P console.log(text.nodeValue); //null var text = p.childNodes[0]; //获取p节点下的text节点 console.log(text.nodeType); //3 console.log(text.nodeName); //#text console.log(text.nodeValue); //hello world! text.nodeValue = "ok!!!"; //将会修改p标签下的内容 console.log(text.nodeValue); //ok!!!
Document类型
JavaScript通过Document类型表示文档。document对象是HTMLDocument(继承自Document 类型)的一个实例,表示整个HTML页面。document对象是window对象的一个属性,因此可以将其作为全局对象来访问;不仅可以取得与页面有关的信息,而且还能操作页面的外观及其底层结构。
- nodeType 的值为9;
- nodeName 的值为"#document";
- nodeValue 的值为null;
Element类型
提供了对元素标签名、子节点及特性的访问。
- nodeType 的值为1;
- nodeName 的值为元素的标签名;
- nodeValue 的值为null
Text类型
包含的是可以照字面解释的纯文本内容。
- nodeType 的值为3;
- nodeName 的值为"#text";
- nodeValue 的值为节点所包含的文本;
Comment类型
在DOM中通过Comment 类型来表示注释。
- nodeType 的值为8;
- nodeName 的值为"#comment";
- nodeValue 的值是注释的内容;
DOM操作
获取网页信息
document.title, 通过这个属性可以获取和修改当前页面的标题;
document.URL, 包含页面完整的URL(即地址栏中显示的URL);
document.domain, 页面的域名;
document.referrer, 链接到当前页面的上一个页面的URL;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
document.title = "JavaScript DOM"; console.log(document.title); //JavaScript DOM console.log(document.URL); //http://localhost:63342/python/frontend/DOM.html console.log(document.domain); //localhost console.log(document.referrer); //http://localhost:63342/python/frontend/BOM.html
获取元素
getElementById(id), 获取文档中指定惟一ID属性值的元素;
getElementsByClassName(str), 返回一个包含了所有指定类名的子元素的HTML集合;
getElementsByTagName(str), 返回一个包括所有指定标签名称的元素的HTML集合;
getElementsByName(str), 根据给定的name返回一个HTML集合。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var element1 = document.getElementById("a1"); //获取id为a1的元素 var element2 = document.getElementsByClassName("c1"); //class中包含c1的元素集合 var element3 = document.getElementsByTagName("p"); //所有p元素的集合 var element4 = document.getElementsByName("username"); //name属性为username的元素集合 var ele5 = element1.getElementsByClassName("b1"); //element1节点下class中包含b1的元素集合 var ele6 = element1.getElementsByTagName("p"); //element1节点下name属性为username的元素集合
children:返回所有子元素的结合;
childElementCount:返回子元素(不包括文本节点和注释)的个数;
firstElementChild:指向第一个子元素;firstChild 的元素版;
lastElementChild:指向最后一个子元素;lastChild 的元素版;
previousElementSibling:指向前一个同辈元素;previousSibling 的元素版;
nextElementSibling:指向后一个同辈元素;nextSibling 的元素版;
parentElement:指向父级元素。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//假设a1元素下有子元素b1, b2, b3,b2元素下有子元素c1, c2, c3。 var ele = document.getElementById("b2"); //直接获取到b2元素 console.log(ele.children); //HTMLCollection(3) [div.c1, div.c2, div.c3] console.log(ele.firstElementChild); //<div class="c1">c1</div> console.log(ele.lastElementChild); //<div class="c3">c3</div> console.log(ele.nextElementSibling); //<div id="b3">b3</div> console.log(ele.previousElementSibling); //<div id="b1">b1</div> console.log(ele.parentElement); //<div id="a1">...</div>
节点操作
createElement(ele), 创建指定类型的元素对象;
appendChild(ele), 末尾处添加子元素对象;
removeChild(ele), 末尾处删除子元素对象;
replaceChild(new,old), 将old元素节点替换为new元素;
insertBefore(ele,ref_ele), 将新元素插入到指定子元素前面;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//HTML初始结构 <div id="total"> <div id="one">one</div> <div id="two">two</div> <div id="tree">tree</div> </div> //获取DOM中的元素对象 var ele = document.getElementById("total"); var one = document.getElementById("one"); var two = document.getElementById("two"); var tree = document.getElementById("tree"); //创建新的元素对象 var newEle = document.createElement("div"); newEle.innerText = "hello world!"; //修改元素节点的子树 ele.appendChild(newEle); ele.removeChild(one); ele.replaceChild(one, tree); ele.insertBefore(tree, two); //执行结果 <div id="total"> <div id="tree">tree</div> <div id="two">two</div> <div id="one">one</div> <div name="goodboy">hello world!</div> </div>
属性操作:
value:获取值,即form提交表单的值;
innerHTML:获取或设置元素节点的文本内容,识别HTML代码,可以通过HTML代码直接修改DOM节点内部的子树;
innerText:获取或设置元素文本内容,不返回隐藏元素的文本;
textContent:获取或设置元素文本内容,返回所有文本。
attributes,获取元素所有属性;
getAttribute(name), 获取元素中属性的值。
setAttribute(name, value), 设置元素中属性的值;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//HTML初始结构 <div id="total"> <div id="one">one</div> <div id="two">two</div> <div id="tree">tree</div> </div> //获取DOM中的元素对象 var ele = document.getElementById("total"); var one = document.getElementById("one"); var two = document.getElementById("two"); var tree = document.getElementById("tree"); //修改元素对象的属性 one.innerHTML = "<span>hello world!</span>>"; two.innerText = "hello world!"; tree.setAttribute("name", "goodboy"); var nameValue = newEle.getAttribute("name"); console.log(nameValue); //goodboy //执行结果 <div id="total"> <div id="one"><span>hello world!</span></div> <div id="two">hello world!</div> <div id="tree" name="goodboy">one</div> </div>
多选框是type为checkbox的input元素对象,对象中有一个checked属性,是记录是否被选中的;只需要对这个属性进行自定义修改,就可以实现全选、反选等功能。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>checkbox</title> <style> .box{ } </style> </head> <body> <div> <input type="button" value="全选" onclick="checkAll()"> <input type="button" value="反选" onclick="reverseAll()"> <input type="button" value="取消" onclick="cancelAll()"> </div> <div style="margin: 20px"> <div><input type="checkbox" value="11" class="box"><span>11</span></div> <div><input type="checkbox" value="22" class="box"><span>22</span></div> <div><input type="checkbox" value="33" class="box"><span>33</span></div> <div><input type="checkbox" value="44" class="box"><span>44</span></div> <div><input type="checkbox" value="55" class="box"><span>55</span></div> </div> <script> function getElementList() { return document.getElementsByClassName("box"); } function checkAll() { var elementList = getElementList(); for (var i in elementList) { elementList[i].checked = true; } } function cancelAll() { var elementList = getElementList(); for (var i in elementList) { elementList[i].checked = false; } } function reverseAll() { var elementList = getElementList(); for (var i=0; i<elementList.length; i++) { if (elementList[i].checked){ elementList[i].checked = false; } else { elementList[i].checked = true; } } } </script> </body> </html>
类属性操作
className:获取或设置调用方法的元素对象的class属性值;
clasList:是只读的属性,返回元素的所有类名,作为DOMTokenList对象。
classList.add(cls):添加指定的类值,如果这些类已存在于元素的class属性中,则会忽略它们;
classList.remove(cls):删除指定的类值。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//HTML初始化结构 <div id="one" class="red">one</div> <div id="two" class="big bold">two</div> <div id="tree" class="red big bold">tree</div> var one = document.getElementById("one"); var two = document.getElementById("two"); var tree = document.getElementById("tree"); console.log(tree.className); //red big bold one.classList.add("bold"); two.classList.remove("bold"); //渲染结果 <div id="one" class="red bold">one</div> <div id="two" class="big">two</div> <div id="tree" class="red big bold">tree</div>
css样式操作
任何支持style 特性的HTML 元素在JavaScript 中都有一个对应的style 属性;这个style 对象是CSSStyleDeclaration 的实例,包含着通过HTML 的style 特性指定的所有样式信息,但不包含与外部样式表或嵌入样式表经层叠而来的样式。使用短划线的CSS 属性名,必须将其转换成驼峰大小写形式。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var myDiv = document.getElementById("myDiv"); //设置背景颜色 myDiv.style.backgroundColor = "red"; //改变大小 myDiv.style.width = "100px"; myDiv.style.height = "200px"; //指定边框 myDiv.style.border = "1px solid black";
DOM事件流
JavaScript 与HTML之间的交互是通过事件实现的。
“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会。然后是实际的目标接收到事件。最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。
在DOM 事件流中,实际的目标(<div>元素)在捕获阶段不会接收到事件。这意味着在捕获阶段,事件从document 到<html>再到<body>后就停止了。下一个阶段是“处于目标”阶段,于是事件在<div>上发生,并在事件处理中被看成冒泡阶段的一部分。然后,冒泡阶段发生,事件又传播回文档。
事件捕获:不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件;
事件处理:事件就是用户或浏览器自身执行的某种动作,而响应某个事件的函数就叫做事件处理程序;
事件冒泡:即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。
事件对象
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息;包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<input id="click" type="button" value="点击" onclick="alert(event.type)"> <input id="click" type="button" value="点击" onclick="clickFunc(event)"> function clickFunc(event) { alert(event.type); } <input id="click" type="button" value="点击"> var butt = document.getElementById("click"); butt.onclick = function (event) { alert(event.type); }
对象属性
type:包含事件类型的字符串;
target:对事件调度的对象的引用,最终落实的元素;
currentTarget:对事件处理程序附加到的元素的引用,而不是target;对象this始终等于currentTarget的值;
bubbles:表明事件是否冒泡;
cancelable:表明是否可以取消事件的默认行为;
detail:与事件相关的细节信息;
view:发生事件的window对象。
如果直接将事件处理程序指定给了目标元素,则this、currentTarget和target包含相同的值。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<body> <input id="click" type="button" value="点击"> </body> <script> var butt = document.getElementById("click"); butt.onclick = function () { console.log(event.type); //click console.log(event.target); //<input id="click" type="button" value="点击"> console.log(this); //<input id="click" type="button" value="点击"> console.log(event.currentTarget); //<input id="click" type="button" value="点击"> console.log(event.currentTarget === this); //true } </script>
如果事件处理程序存在于按钮的父节点中(例如document.body),那么这些值是不相同的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<body> <input id="click" type="button" value="点击"> </body> <script> document.body.onclick = function () { console.log(event.target); //<input id="click" type="button" value="点击"> console.log(this); //<body>...</body> console.log(event.currentTarget); //<body>...</body> console.log(event.currentTarget === this); //true } </script>
对象方法
preventDefault():取消事件的默认行为;如果cancelable是true,则可以使用这个方法;
stopPropagation():取消事件的进一步捕获或冒泡。如果bubbles为true,则可以使用这个方法;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//点击a标签时,阻止跳转页面 var ele = document.getElementById("myLink"); ele.onclick = function () { event.preventDefault() } //当点击按钮时,阻止事件向上冒泡 var btn = document.getElementById("myButton"); btn.onclick = function () { alert("button is clicked"); event.stopPropagation(); }; document.body.onclick = function () { alert("body is clicked") }
事件类型
UI事件
onload:资源被加载完
onunload:资源被卸载
onabort:图象的加载被中断
onerror:在加载文档或图像时发生错误
onselect:当用户选择文本框中的一或多个字符时触发
onresize:当窗口或框架的大小变化时
onscroll:当用户滚动带滚动条的元素中的内容时
焦点事件
onfocus:元素获得焦点
onblur:元素失去焦点
鼠标事件
onclick:在用户单击主鼠标按钮或者按下回车键时触发
ondblclick:在用户双击主鼠标按钮时触发
onmouseup:在用户释放鼠标按钮时触发
onmousedown:在用户按下了任意鼠标按钮时触发
onmouseover:在鼠标移入一个元素边界之内时触发
onmousemove:当鼠标在元素内部移动时重复地触发
onmouseout:在鼠标从一个元素上方移开时触发;
键盘事件
onkeydown:某个键盘按键被按下
onkeypress:某个键盘按键被按下并松开
onkeyup:某个键盘按键被松开
form事件
onchange:区域的内容被修改
onreset:重置按钮被点击
onsubmit:确认按钮被点击