JavaScript基础系列9---DOM操作
2016-12-08 20:13
776 查看
一、DOM概述
1.1 DOM概念
DOM(文档对象模型)是针对 HTML 和 XML 文档的一个 API(应用程序编程接口)。DOM 描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。
W3C DOM标准分为3部分:
core DOM - 针对任何结构化文档的标准模型
XML DOM - 针对 XML 文档的标准模板
HTML DOM - 针对 HTML 文档的标准模型
备注:HTML DOM 是关于如何获取、修改、添加或删除 HTML 元素的标准,即操作HTML的元素
DOM级别
DOM Level 1:于1998年10月成为W3C的推荐标准。DOM 1级由两个模块组成:DOM核心(DOM Core)和DOM HTML。
DOM Level 2:对DOM level 1做了扩展
DOM Level 3:对DOM level 2做了进一步的扩展
DOM Level 0: 首先我们的确定的是在DOM标准中并没有DOM 0级的。所谓的DOM 0级是DOM历史坐标中的一个参照点而已,具体说呢,DOM 0级指的是IE4和Netscape 4.0这些浏览器最初支持的DHTML。
1.2 DOM节点概述
看下面的一段HTML:<html> <head> <title>DOM节点分类</title> </head> <body> <p id="p">育知同创欢迎你!</p> </body> <!-- 注释 --> </html>
说明:
document节点是每个文档的根节点
document节点下面只有一个 html节点,我们称之为文档元素。(documentElement)
文档元素是文档的最外层元素,其他元素都包含在文档元素中。
一个文档只能有一个文档元素,在html中文档元素永远是 元素。
在DOM树中,html文档中每一处标记都可以用树中的一个节点来表示。
html(元素)标签,通过元素节点表示
属性,通过属性节点来表示
文档类型,通过文档类型节点来表示
注释,通过注释类型来表示
1.3 DOM节点分类
DOM中,共有12中节点类型,每一个节点,必是这12中类型中的一种。Node.ELEMENT_NODE (1) //元素
Node.ATTRIBUTE_NODE (2) //元素的属性
Node.TEXT_NODE (3) //
Node.CDATA_SECTION_NODE (4) //子节点一定为TextNode
Node.ENTITY_REFERENCE_NODE (5) //文档中的实体引用
Node.ENTITY_NODE (6) //
Node.PROCESSING_INSTRUCTION_NODE (7) //表示一个文档处理程序使用的特有指令。,无子节点
Node.COMMENT_NODE (8) //注释
Node.DOCUMENT_NODE (9) //最外层的Root element,包括所有其它节点 根节点
Node.DOCUMENT_TYPE_NODE (10) //DTD, 每个文档节点都有一个DocumentType节点,它提供文档类型的定义。
Node.DOCUMENT_FRAGMENT_NODE (11) //可以将文档片段看作轻量级或者更小型的Document节点。定义这种数据类型是因为通常希望只提取文档的一部分来处理。
Node.NOTATION_NODE (12) //DTD中的Nation定义 在XML文档中表示一个符号。
可以通过获取一个节点的nodeType属性来得到节点的类型。
经常用到了比较重要的节点:(记住每个节点的数字值)
元素类型 | NodeType |
---|---|
元素 | 1 |
属性 | 2 |
文本 | 3 |
注释 | 8 |
文档 | 9 |
1.4 节点属性(特性)
nodeName:节点名称(nodeName 始终包含 HTML 元素的大写字母标签名) nodeName 是只读的元素节点的 nodeName 与标签名相同
属性节点的 nodeName 与属性名相同(元素.getAttributeNode(“属性名”)获取属性节点)
文本节点的 nodeName 始终是 #text(通过元素的子节点获取)
注释节点的nodeName是#comment(通过元素的子节点获取)
文档节点的 nodeName 始终是 #document
nodeValue:节点值 (设置或返回节点的值)
元素节点的 nodeValue 是 undefined 或 null
属性节点的 nodeValue 是属性值
文本节点的 nodeValue 是文本本身
注释节点的nodeValue是注释里面的内容
文档节点的nodeValue 是null
nodeType:节点类型
元素 element 1
属性 attr 2
文本 text 3
注释 comments 8
文档 document 9
二、DOM核心对象—document对象
JavaScript 通过 Document 类型表示文档。在浏览器中, document 对象是 HTMLDocument (继承自 Document 类型)的一个实例,表示整个 HTML 页面。而且, document 对象是 window 对象的一个
属性,因此可以将其作为全局对象来访问。
nodeType 的值为 9;
nodeName 的值为 “#document” ;
nodeValue 的值为 null ;
parentNode 的值为 null ;
ownerDocument 的值为 null ;
其子节点可能是一个 DocumentType (最多一个)、 Element (最多一个)、 ProcessingInstruction
或 Comment
通过document对象,不仅可以取得与页面有关的信息,而且还能操作页面的外观及其底层结构。
2.1 获取节点方法1:getElementById(id)
在整个文档中,根据元素id来获取元素节点<body> <h1 id="myH1" class="hTitle">这个是标题</h1> <script type="text/javascript"> //根据id获取元素 var h1 = document.getElementById("myH1"); alert(h1.id); //查看这个元素的id alert(h1.className); //元素的 className alert(h1.innerHTML); //查看元素包含的所有HTML文本 </script> </body>
注意:
如果有多个元素的id相同,则只返回第一个元素。一般情况,不要给多个元素起同名id
2.2 获取节点方法2:getElementsByTagName(tagName)
根据标签名获取元素节点。因为一个文档中会有多个同名标签,所以这个方法返回的是多个Element组成的集合为了提高性能,在开发的时候应该尽量避免使用这种方式去查找元素,应该使用getElementById
<body> <h1 id="myH1" class="hTitle">这个是标题1</h1> <h1 id="myH2" class="hTitle">这个是标题2</h1> <h1 id="myH3" class="hTitle">这个是标题3</h1> <script type="text/javascript"> var h1s = document.getElementsByTagName("h1"); alert(h1s.length); for (var i = 0; i < h1s.length; i++) { alert(h1s[i].id); //可以通过下标访问 ht[i] alert(h1s.item(i).id); // 也可以通过item下标访问 item(i) } </script> </body>
2.3 获取节点方法3:getElementByName(name)
这个是通过标签的name属性的值来获取元素的。由于会出现多个元素name属性的值相等,所以返回的是多个Element组成的集合.注意:不是所有的元素都有name属性,只有 表单标签 才有。而且某些低版本浏览器兼容有问题。慎用
<body> <form action=""> 爱好:<br/> <input type="checkbox" name="lover" value="swimming">游泳<br/> <input type="checkbox" name="lover" value="net">上网 </form> <script type="text/javascript"> var lovers = document.getElementsByName("lover"); for (var i = 0; i < lovers.length; i++) { alert(lovers[i].value); //alert(lovers.item(i).value) } </script> </body>
2.4 获取节点的方法4:querySelector(css选择器)
参数:必须。指定一个或多个匹配元素的 CSS 选择器。 可以使用它们的 id, 类, 类型, 属性, 属性值等来选取元素。对于多个选择器,使用逗号隔开,返回一个匹配的元素。
返回值:匹配指定 CSS 选择器的 第一个元素 。 如果没有找到,返回 null。
<body> <p id="demo">id="demo" 的 第一个 p 元素</p> <p id="demo">id="demo" 的 第二个 p 元素</p> <button onclick="myFunction()">点我修改id = demo 的第一个元素内容</button> <script> function myFunction() { //返回第一个id=demo的元素 document.querySelector("#demo").innerHTML = "Hello World!"; } </script> </body>
document.querySelector("p"); // 获取文档中第一个p元素(元素选择器) document.querySelector("p.example"); //获取文档中 class="example" 的第一个 <p> 元素:
2.5 获取节点的方法5:querySelectorAll(css选择器)
querySelector只能获取第一个满足条件的元素,如果想获取所有满足条件的元素,可以使用HTML5引入的新方法qureySelectorAll<body> <p id="demo">id="demo" 的 第一个 p 元素</p> <p id="demo">id="demo" 的 第二个 p 元素</p> <button onclick="myFunction()">点我修改id = demo 的所有元素</button> <script> function myFunction() { var all = document.querySelectorAll("#demo"); for (var i = 0; i < all.length; i++) { all[i].innerHTML = "哈哈哈" } } </script> </body>
2.6 获取documentElement元素
documentElement 属性以一个元素对象返回一个文档的文档元素。HTML 文档返回对象为 HTML元素。<body> <script type="text/javascript"> alert(document.documentElement.nodeName); // html alert(document.documentElement.nodeValue); // null alert(document.documentElement.nodeType); // 1 </script> </body>
三、Node关系—获取操作
3.1 节点与节点之间的关系
说明:父(parent)节点 父节点拥有任意数量的子节点
子(child)节点 子节点拥有一个父节点
兄弟(sibling)节点 同级的子节点被称为同胞(兄弟或姐妹)。同胞是拥有相同父节点的节点
根 (root) 节点 一个文档只能有一个根节点。对html文档来说,根节点就是documentElement。根节点不可能有父节点
3.2 childNodes属性:获取一个元素的所有子节点
childNodes:获取所有子节点。(但是不能获取到子节点的子节点)<body> <div id="div"> <a href="">搜狐</a> <div> <a href=""></a> </div> <input type="text" name="user" /> </div> <script type="text/javascript"> //通过Element元素的childNodes属性获取到这个元素下面的所有直接子节点 var nodes = document.getElementById("div").childNodes; for (var i = 0; i < nodes.length; i++) { alert(nodes[i].nodeName) } </script> </body>
3.3 firstChild属性:获取一个元素的第一个子节点
如果选定的节点没有子节点,则该属性返回 NULL。<body> <div id="div"><a href="">搜狐</a> <div> <a href=""></a> </div> <input type="text" name="user" /> </div> <script type="text/javascript"> var div = document.getElementById("div"); var fistChild = div.firstChild; //第一个子节点 alert(fistChild.nodeName); // A </script> </body>
3.4 lastChild属性:获取一个元素的最后一个子节点
lastChild 属性可返回文档的最后一个子节点。<body> <div id="div"><a href="">搜狐</a> <div> <a href=""></a> </div> <input type="text" name="user" /></div> <script type="text/javascript"> var div = document.getElementById("div"); var lastChild = div.lastChild; //最后一个节点 alert(lastChild.nodeName); // INPUT </script> </body>
3.4 parentNode属性:获取一个元素的父节点
<body> <div id="div"><a href="">搜狐</a> <div> <a href=""></a> </div> <input type="text" name="user" /></div> <script type="text/javascript"> var div = document.getElementById("div"); var parentNode = div.parentNode; //父节点 alert(parentNode.nodeName); // BODY </script> </body>
3.5 previousSibling属性:获取一个元素的上一个兄弟节点
<body> <div id="div"><a href="">搜狐</a><div id="div1"> <a href=""></a> </div> <input type="text" name="user" /></div> <script type="text/javascript"> var div1 = document.getElementById("div1"); var preSibling = div1.previousSibling; //获取div1的父节点 alert(preSibling.nodeName); // A </script> </body>
3.6 nextSibling属性:获取一个元素的下一个节点
<body> <div id="div"><a href="">搜狐</a> <div id="div1"> <a href=""></a> </div> <input type="text" name="user" /> </div> <script type="text/javascript"> var div1 = document.getElementById("div1"); var neSibling = div1.nextSibling; // 下一个兄弟节点 alert(neSibling.nodeName); // #text </script> </body>
==补充:由于上述都是节点操作,所以获取到的节点会包含一些我们并不关心的内容,比如空节点。下面的几个api只获取元素节点。==
四、Node关系—修改操作
4.1 createTextNode():创建文本节点
document.createTextNode(text)参数:文本
返回值:创建的文本标签
注意:这个方法是 document的方法,因为创建元素这么大的事,只能document来干,找某个element来创建不靠谱。
<body> <div id="div"></div> <script type="text/javascript"> var textNode = document.createTextNode("我是一个开心的文本!!!"); //创建一个文本节点 alert(textNode.nodeName + "\n" + textNode.nodeValue); // #text 我是一个开心的文本!!! </script> </body>
4.2 appendChild() : 给一个元素添加child节点
element.appendChild(node)参数:必须。表示要添加的节点
返回值:参数对象本身
注意:append的意思是追加。如果元素已经有child,则追加到别的child之后。也就是说新添加的 child 进去之后一定是 lastChild
<body> <div id="div"></div> <script type="text/javascript"> var div = document.getElementById("div"); var textNode = document.createTextNode("我是一个开心的文本!!!"); div.appendChild(textNode); //把刚才创建的文本添加到div标签中。 </script> </body>
4.3 createElement(nodename): 创建元素节点
document.createElement(nodename)参数:必须。要创建的元素的名称
返回:创建的元素节点
<body> <div id="div"></div> <script type="text/javascript"> var div = document.getElementById("div"); var newElement = document.createElement("a"); //创建一个a标签 var textNode = document.createTextNode("首页"); // 创建一个文本节点 newElement.appendChild(textNode); //把 文本节点添加到a标签中 var v = div.appendChild(newElement); // 把刚刚创建的a标签,添加为div标签的子标签 alert(v === newElement) // true 证明参数和返回值确实为同一个对象 </script> </body>
4.4 insertBefore() : 在一个节点前插入新节点
node.insertBefore(newnode,existingnode)参数1:要插入的新节点
参数2:目标节点。会把参数1节点插入这个节点之前。
<body> <ul id="language"> <li>java</li> <li>c++</li> </ul> <button onclick="myFunction()">点我在java前插入JavaScript</button> <script> function myFunction() { var newItem = document.createElement("li") var textnode = document.createTextNode("JavaScript") newItem.appendChild(textnode) var languageList = document.getElementById("language") //把newItem添加到languageList的第1个子节点之前 languageList.insertBefore(newItem, list.firstChild); } </script> </body>
4.5 removeChild(): 移除子节点
node.removeChild(node)参数:必须。要移除的那个子节点
<body> <ul id="language"> <li>java</li> <li>c++</li> <li>oc</li> <li>php</li> <li>c#</li> <li>JavaScript</li> </ul> <button onclick="myFunction()">点我移除第1条语言</button> <script> function myFunction() { var languageList = document.getElementById("language"); //获取到languageList下面的所有的 li 标签 var liList = languageList.getElementsByTagName("li"); // 移除第一个 li 元素。 如果重复调用,则每次都是移除第1个 languageList.removeChild(liList[0]); alert(liList.length) } </script> </body>
4.6 replaceChild():替换子节点
node.replaceChild(newnode,oldnode)参数1:新节点
参数2:旧节点
<body> <ul id="language"> <li>java</li> <li>c++</li> <li>oc</li> <li>php</li> <li>c#</li> <li>JavaScript</li> </ul> <button onclick="myFunction()">点我替换第一条语言</button> <script> function myFunction() { var languageList = document.getElementById("language"); var newLi = document.createElement("li"); newLi.innerHTML="JavaScript"; //用新节点去替换旧节点。 languageList.replaceChild(newLi, languageList.childNodes[1]); } </script> </body>
4.6 cloneNode():克隆节点
node.cloneNode(deep):cloneNode() 方法可创建指定的节点的精确拷贝。拷贝所有属性和值。
该方法将复制并返回调用它的节点的副本。如果传递给它的参数是 true,它还将递归复制当前节点的所有子孙节点。否则,它只复制当前节点。
<body> <ul id="language"> <li>java</li> <li>c++</li> <li>oc</li> <li>php</li> <li>c#</li> <li>JavaScript</li> </ul> <button onclick="myFunction()">点我clone整个列表</button> <script> function myFunction() { var languageList = document.getElementById("language"); //克隆languageList整个节点,传入true表示深度copy,所有的子节点都copy var newList = languageList.cloneNode(true); document.getElementsByTagName("body")[0].appendChild(newList); } </script> </body>
五、元素属性操作
在HTML中,一个元素会有很多属性,比如id属性,class属性,title属性等等,如何操作这些呢?5.1 getAttribute():获取属性值
element.getAttribute(attributename)返回元素的指定属性的值。
参数:元素的某个属性的名 (id, className, title)
<body> <a id="id1" href="http://www.yztcedu.com" target="_blank">育知同创官网</a>. <br /> <p> <button onclick="myFunction()">点我获取超级链接的 id 属性值,tafget 属性值</button> </p> <script> function myFunction() { var a1 = document.getElementById("id1"); alert("id = " + a1.getAttribute("id") + "\ntarget = " + a1.getAttribute("target")); } </script> </body>
5.2 setAttribute(): 设置属性值
element.setAttribute(attributename,attributevalue)作用:创建建或改变某个新属性。如果指定属性已经存在,则只设置该值。如果属性不存在,则创建该属性并设置属性值。
参数1:属性名
参数2:新的属性值
<body> <input value="OK" > <br/> <button onclick="myFunction()">点我把上述文本框的 type 属性设置为 button 样式</button> <script> function myFunction() { var inputs = document.getElementsByTagName("input"); //把input的 type属性设置为button inputs[0].setAttribute("type", "button"); }; </script> </body>
5.2 removeAttribute() : 移除属性
element.removeAttribute(attributename)参数:必需。规定要删除的属性的名称。
<body> <input id="input1" type="button" value="点我可以转换我的状态" onclick="myFunction();"> <script> function myFunction() { var input1 = document.getElementById("input1"); var typeValue = input1.getAttribute("type"); if(typeValue){ input1.removeAttribute("type"); //如果type属性有值就把这个属性去掉 }else { input1.setAttribute("type", "button"); //如果type属性不存就添加属性。 } }; </script> </body>
六、元素节点的常用属性
元素节点除了有所有的节点都有的属性比如:nodeName、nodeValue、nodeType外,还有一些特有的属性,来方便操作标签元素。6.1 tagName属性
tagName属性是nodeName的另一中写法。注意区别是:tagName只在标签节点中有,而nodeName在所有类型的(12种)节点中都存在。它的值表示的就是标签的名字。
<body> <p id="p1">我是一个p标签</p> <script type="text/javascript"> var p1 = document.getElementById("p1"); alert(p1.tagName); // p </script> </body>
6.2 innerHTML属性
innerHTML 属性设置或返回标签的开始和结束标签之间的 HTML。值为为文本
注意:这个属性的值是这个标签的开始和结束部分之间的所有内容,但是
<body> <p id="p1"><a href="http://www.yztcedu.com">点我进入育知同创官网</a></p> <P><button onclick="getHTML();">点我获取超级链接的所有内容</button></P> <p><button onclick="setHTML();">点我更改整个超级链接</button></p> <script type="text/javascript"> var p1 = document.getElementById("p1"); function getHTML () { alert(p1.innerHTML); } function setHTML () { p1.innerHTML = "<a href='https://www.baidu.com'>点我进入百度主页</a>" } </script> </body>
6.3 innerText属性
innerText值获取标签中的文本内容,子标签本身不会获取到。去修改的时候,即使带有标签也会把标签作为纯文本来对待,而不会解析为标签
<body> <p id="p1"><a href="http://www.yztcedu.com">点我进入育知同创官网</a></p> <P><button onclick="getHTML();">点我获取超级 链接的所有内容</button></P> <p><button onclick="setHTML();">点我更改整个超级链接</button></p> <script type="text/javascript"> var p1 = document.getElementById("p1"); function getHTML () { alert(p1.innerText); } function setHTML () { p1.innerText = "<a href='https://www.baidu.com'>点我进入百度主页</a>" } </script> </body> //其实还有一个属性:textContent 和innerText的作用相同。
6.4 id属性
就是指的元素节点的id属性的值,与getAttribute(“id”)的值是一样的。6.5 className属性
className 属性设置或返回元素的 class 属性。(因为class在js中是关键字,所以这个地方把属性名字改成了className)<body> <p class="p1">这是一个段落</p> <script type="text/javascript"> var p1 = document.querySelector(".p1"); alert(p1.className); </script> </body>
6.7 value属性
如果一个标签可以拥有value值,则可以可以通过element.value来获取。一般表单数据才具有vlaue:input、textarea、select
<body> <input id="in1" type="text" value="abc" /> <p> <button id="btn" onclick="getValue();" value="abc">获取上面输入框的value属性</button> </p> <script type="text/javascript"> var in1 = document.getElementById("in1"); function getValue () { alert(in1.value); // 获取标签的value值 } </script> </body>
七、样式表的属性—css脚本化
可以通过JavaScript访问css的属性,并修改css属性7.1 获取和修改行间样式表
有2中方式访访问到行间样式表element.style.css属性名
element.style[“属性名”]
<body> <div id="box1"></div> <script type="text/javascript"> var box1 = document.getElementById("box1"); box1.style.width = "100px"; //设置css属性. 设置所有属性都要使用引号括起来。 box1.style["height"] = "100px"; box1.style.backgroundColor = "blue"; alert(box1.style["width"]); </script> </body>
7.2 获取内部样式表和外部样式表
对ie浏览器:对象.currentSytle[“属性名”]其他浏览器:window.getComputedStyle(对象,null)[“属性名”]
注意:内部样式表中的属性和外部样式表中的属性只能获取不能修改。如果想修改需要通过行间样式表修改,行间样式表的优先级最高,会覆盖内部样式表和外部样式表。
<body> <div id="box1"></div> <script type="text/javascript"> var box1 = document.getElementById("box1"); // alert(box1.currentStyle["width"]); //只支持IE浏览器 // alert(window.getComputedStyle(box1, null)["height"]); //支持浏览器外的其他浏览器 alert(getStyle(box1, "backgroundColor")); /* 为了简化书写和兼容浏览器,一般封装一个方法出来 */ function getStyle (obj, attributeName) { if(obj.currentStyle){ //如果存在对象,则是在ie浏览器 return obj.currentStyle[attributeName]; }else { //其他浏览器 return window.getComputedStyle(obj, null)[attributeName]; } } </script> </body>
补充:
offsetWidth、offsetHeight 可以获取宽和高,包括 border 和 padding,其实是这个元素的实际占据的空间。但是只能获取不能修改
相关文章推荐
- javascript DOM操作基础
- javascript DOM操作基础
- javascript基础DOM操作
- JavaScript基础:DOM操作详解
- JavaScript基础系列7---字符串操作和数学函数
- javascript DOM操作基础
- JavaScript DOM编程基础精华03(动态设置,层的操作,性能问题)
- JavaScript DOM操作基础笔记
- SVG基础以及使用Javascript DOM操作SVG
- JavaScript基础之操作DOM
- javascript基础。dom操作
- JavaScript基础 DOM的操作
- JavaScript基础语法、dom操作树及document对象
- 总结---JavaScript基础DOM操作
- javascript DOM 操作基础知识小结
- JavaScript-DOM操作基础部分的内容
- JavaScript基础----20Javascript-DOM操作HTML
- JavaScript基础----21Javascript-DOM操作CSS
- javascript基础DOM操作
- JavaScript基础DOM操作