JavaScript笔记:DOM
来源:互联网 发布:管家婆sql下载 编辑:程序博客网 时间:2024/05/16 06:44
DOM对象是针对HTML和XML文档的一个API。DOM描绘了一个层次化的节点树,允许开发人员添加修改页面的一部分。
节点层次
DOM可以将HTML和XML文档描绘成一个多层节点组成的结构。节点分为不同的类型,每种类型分别表示文档中不同的信息或标记。每个节点都拥有各自的特点、数据和方法,与其它节点也可能存在某种关系。节点之间的关系构成了层次,所有页面的标记则表现为以特定节点为跟节点的树形结构。
1、Node类型
DOM1级定义了一个Node接口,该接口将由DOM中的所有节点类型实现。这个Node接口在JS中是作为Node类型实现的,除了IE浏览器之外,其他所有的浏览器都可以访问到这个类型。JS中所有的节点都继承自Node类型,因此所有的节点都共享着相同的基本属性和方法。
每个节点都有一个nodeType属性,用于表示节点的类型。节点类型由在Node类型中定义的下列12个数值常量表示,任何节点类型必居其一。
Node.ELEMENT_NODE(1) Node.ATTRIBUTE_NODE(2) Node.TEXT_NODE(3) Node.CDATA_SECTION_NODE(4) Node.ENTITY_REFERENCE_NODE(5) Node.ENTITY_NODE(6) Node.PROCESSING_INSTRUCTION_NODE(7) Node.COMMENT_NODE(8)Node.DOCUMENT_NODE(9) Node.DOCUMENT_TYPE_NODE(10) Node.DOCUMENT_FRAGMENT_NODE(11) Node.NOTATION_NODE(12)。
通过比较上面这些常量,可以很容易的确定节点的类型。
if (someNode.nodeType == 1){ //在所有浏览器中有效 alert("Node is an element.");}
nodeName和nodeValue属性:
要了解节点的具体信息,可以使用nodeName和nodeValue属性。这两个属性完全取决于节点的类型。
检查节点类型:
if (document.getElementById("first").nodeType == 1){ value = document.getElementById("first").nodeName; console.log(value);// DIV}
对于元素节点,nodeName保存的是元素的标签名,而nodeValue始终为null。
节点关系:
文档中的所有节点都存在这样或那样的关系。节点之间的关系就好像家族的家谱树。例如,在HTML中body是html元素的子元素,反过来说,html元素就是body元素的父元素。而head元素,则可以看成是body元素的同胞元素。每个节点都有一个childNodes属性,保存着一个NodeList对象,注意,NodeList对象并不是Array的实例,它是对DOM动态查询的结果。
使用方法:
var firstChild = someNode.childNodes[0];var secondChild = someNode.childNodes.item(1);var count = someNode.childNodes.length;
使用下列方法可以将NodeList转化为数组:
function convertToArray(nodes){ var array = null; try { array = Array.prototype.slice.call(nodes, 0); // IE中无效 } catch (ex) { array = new Array(); for (var i=0, len=nodes.length; i < len; i++){ array.push(nodes[i]); } } return array;}
每个节点都有一个parentNode的属性,指向文档中的父节点。包含在childNodes列表中的所有节点都有相同的父节点。另外,包含在childNodes列表中的所有节点都是同胞节点,可以使用节点属性previousSibling/nextSibling来访问节点的同胞节点。
if (someNode.nextSibling === null){ alert("Last node in the parent’s childNodes list.");} else if (someNode.previousSibling === null){ alert("First node in the parent’s childNodes list.");}
父节点的firstChild和lastChild分别指向其子节点的第一个和最后一个节点。
另外hasChildNodes()也是一个好用的方法,当节点包含子节点的时候,该方法返回true。
所有节点都有的最后一个属性是ownerDocument,该属性指向表示整个文档的文档节点。
操作节点:
因为关系指针都是只读的,所以DOM提供了一些操作节点的方法。其中,最常用的就是appendChild()方法,用于向childNodes列表的末尾添加一个节点。更新完成后,appendChild()方法返回新增的节点。
var returnedNode = someNode.appendChild(newNode); alert(returnedNode == newNode); //true alert(someNode.lastChild == newNode); //true
如果传入appendChild函数的节点已经是文档的一部分了,那结果就是将传入的节点移动到指定的位置。
如果需要把指定节点放在childNodes列表的某个特定位置上,而不是最后一个,那么就需要用到insertBefore方法。这个方法接受两个参数:要插入的节点和作为参照的节点。如果参照节点是null,那么insertBefore方法就和appendChild方法的作用一样了。
//插入后成为最后一个节点 returnedNode = someNode.insertBefore(newNode, null); alert(newNode == someNode.lastChild); //true//插入后成为第一个节点 var returnedNode = someNode.insertBefore(newNode, someNode.firstChild); alert(returnedNode == newNode); //truealert(newNode == someNode.firstChild); //true//插入到最后一个节点前面returnedNode = someNode.insertBefore(newNode, someNode.lastChild); alert(newNode == someNode.childNodes[someNode.childNodes.length-2]); //true
replaceChild函数:该函数接受两个参数,要插入的节点和要替换的节点。要替换的节点将由这个函数返回,同时要插入的节点将在DOM中取代被替换掉的节点。
//替换第一个子节点 var returnedNode = someNode.replaceChild(newNode, someNode.firstChild);//替换最后一个子节点returnedNode = someNode.replaceChild(newNode, someNode.lastChild);
如果只想移除而不是替换节点的话,可以使用函数removeChild(),该函数接受一个参数:要移除的节点。
其它方法:
有两个方法是所有类型的节点都具有的:cloneNode(),normalize()。
cloneNode方法接受一个布尔值的参数,表示是否进行深复制。如果进行深复制,那么该节点的所有包括子节点在内的信息都会被复制。如果只是浅复制,那么将只复制节点自身。
例如:
<ul> <li>item 1</li> <li>item 2</li> <li>item 3</li></ul>
假设我们已经将ul节点保存在了myList中,那么下面这段代码就可以让我们看出两种复制的区别。
var deepList = myList.cloneNode(true);alert(deepList.childNodes.length); //3 var shallowList = myList.cloneNode(false);alert(shallowList.childNodes.length); //0
normalize方法用来处理文档树中的文本节点。当在某个节点上调用这个方法时,就会在该节点的后代中查找:1)空文本节点,找到后删除;2)相邻的文本节点,找到后合并成一个。
2、Document类型:
JavaScript通过Document类型表示文档。在浏览器中,document是HTMLDocument的一个实例,表示整个HTML页面。而且document是window对象的一个属性,因此,可以将其作为全局属性来访问。
document节点具有下列属性:
nodeType值为9;
nodeName的值为#document;
nodeValue、parentNode、ownerDocument的值为null。
Document类型可以表示HTML页面,不过最常见的应用还是作为document对象。通过这个对象,不仅可以获得与页面有关的信息,而且还可以操作页面的外观极其底层结构。
1、文档的子节点
document的documentElement属性:该属性始终指向HTML页面中的html元素。另外,document的childNodes也可以用来访问页面的元素。
var html = document.documentElement;//获得对<html>的引用alert(html === document.childNodes[0]);//truealert(html === document.firstChild);//true
作为HTMLDocument的实例,document还有一个属性body,直接指向页面的body标签:
var body = document.body; //取得对<body>的引用
所有的浏览器都支持document.documentElemen和document.body属性。
2、文档信息
作为HTMLDocument文档的一个实例,document还有一些普通Document对象所没有的属性,这些属性提供了document对象所表现的一些网页信息。
例如,title:
//获得文档标题var originalTitle = document.title;//设置文档标题document.title = "New page title";
接下来的三个属性都和网页请求有关:
//取得完整的URLvar url = document.URL;//取得域名var domain = document.domain;//取得来源页面的URLvar referrer = document.referrer;
这三个属性中,只有domain是可以设置的。但是,出于安全性问题的考虑,只能设置成URL中包含的域,否则就会出错:
//假设页面来自于p2p.wrox.com域document.domain = "wrox.com"; //成功document.domain = "nczonline.net"; //出错
浏览器对domain属性还有一个限制,即如果域名一开始是松散的,就不能将其设置为紧绷的。
//假设页面来自于p2p.wrox.com域document.domain = "wrox.com"; //松散的,成功document.domain = "p2p.wrox.com"; //紧绷的,失败
3、查找元素
最常见的DOM应用,应该就是获得特定的某个或某组元素的引用,然后再执行一些操作了。取得元素的操作可以使用document对象的几个方法完成:例如,getElementById()、getElementsByTagName()、getElementsByTagName()。
例子:
var images = document.getElementsByTagName("img");alert(images.length);alert(images[0].src);alert(images.item(0).src);
4、特殊集合
document.anchors:文档中所有带name属性的a标签
document.forms:文档中所有form标签
document.images:文档中所有img标签
document.links:文档中所有带href属性的a标签
5、DOM一致性检测
由于DOM包含了多个级别,也包含了多个部分,因此,检测浏览器实现了DOM的那些部分就十分重要了。
使用方法:
var hasXmlDom = document.implementation.hasFeature("XML", "1.0");
如果浏览器支持该版本,将返回true。
6、文档写入
将输出流写入网页的能力:
<html> <head> <title>document.write() Example</title> </head> <body> <p>The current date and time is: <script type="text/javascript"> document.write("<strong>" + (new Date()).toString() + "</strong>"); </script> </p> </body></html>
此外,还可以使用此方法动态的包含外部资源:
<html> <head> <title>document.write() Example 3</title> </head> <body> <script type="text/javascript"> document.write("<script type=\"text/javascript\" src=\"file.js\">" +"<\/script>"); </script> </body></html>
请注意双引号中的转意字符的写法。
Element类型
Element节点具有以下特点:
nodeType为1
nodeName/tagName为节点的标签名
nodeValue为null
parentNode可能是Document或Element
1、HTML元素
<div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr"></div>// 获取属性var div = document.getElementById("myDiv");alert(div.id);//"myDiv"alert(div.className);//"bd"alert(div.title);//"Body text"alert(div.lang);//"en" 元素内容的语言代码alert(div.dir);//"ltd" 语言的方向// 修改属性div.id = "someOtherId";div.className = "ft";div.title = "Some other text";div.lang = "fr";div.dir ="rtl";
2、取得特性
getAttribute()、setAttribute()、removeAttribute()三个方法:
var div = document.getElementById("myDiv");alert(div.getAttribute("id"));//"myDiv"alert(div.getAttribute("class"));//"bd"alert(div.getAttribute("title"));//"Body text"alert(div.getAttribute("lang"));//"en"alert(div.getAttribute("dir"));//"ltr"
用这个方法可以获得标签自定义的属性:
<div id="myDiv" data-my_special_attribute="hello!"></div>var value = div.getAttribute("my_special_attribute");
另外,有两个特殊的属性,它们通过getAttribute访问或者通过获取元素属性的值得到的结果不同:
第一个是style:当通过getAttribute方法访问时,返回的是字符串,而通过元素的属性的方法访问时,返回的则是一个对象。
第二个是onclick这样的事件处理程序:通过getAttribute访问时,返回的是JS代码的字符串,而通过元素属性访问,返回的则是这个函数。
3、设置特性
div.setAttribute("id", "someOtherId");div.setAttribute("class", "ft");div.setAttribute("title", "Some other text");div.setAttribute("lang","fr");div.setAttribute("dir", "rtl");
4、attributes属性
Element类型是使用attributes属性的唯一的一个DOM节点类型。attributes属性中包含一个NamedNodeMap,是一个动态的集合。NamedNodeMap对象拥有下列方法:
getNamedItem(name):返回nodeName属性等于name的节点。
removeNamedItem(name):从列表中移除nodeName属性等于name的节点。setNamedItem(node):向列表中添加节点,以节点的nodeName属性为索引。
item(pos):返回位于pos位置的节点。
<div id="first" class="mydiv"> 萝卜 </div>// method 1var element = document.getElementById("first");var id = element.attributes.getNamedItem("class").nodeValue;console.log(id);// media// method 2var element = document.getElementsByTagName("div");var id = element[0].attributes.getNamedItem("class").nodeValue;console.log(id);// mydiv
5、创建元素
var div = document.createElement("div");// 为元素添加属性div.id = "myNewDiv";div.className = "box";// 将元素加入DOM树document.body.appendChild(div);// IE下:var div = document.createElement("<div id=\"myNewDiv\" class=\"box\"></div >");
6、元素的子节点
<ul id="myList"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li></ul>var element = document.getElementById("myList");var num = element.childNodes.length;console.log(num);// 7
在不是IE的浏览器下,上面这个ul包含了7个字节点:包括三个li节点和4个文本节点。正确的访问li的方法为:
for (var i=0, len=element.childNodes.length; i < len; i++){ if (element.childNodes[i].nodeType == 1){ //执行某些操作 }}// orvar ul = document.getElementById("myList");var items = ul.getElementsByTagName("li");
Text类型
文本节点由Text类型表示,包含的是纯文本内容。text节点具有一下的特征:
nodeType为3
nodeName为#text
nodeValue为节点包含的文本
parentNode是一个element
没有子节点
可以使用下列方法操作文本:
appendData(text) 将text添加至末尾
deleteData(offset, count) 从offset开始删除count个字符
insertData(offset, text) 从offset开始插入text
replaceData(offset, count, text) 用text替换从offset到offset+count的文本
splitText(offset) 从offset将文本分为两个
substringData(offset, count) 提取从offset到offset+count的文本
<!--没有文本节点--> <div></div><!--有1个文本节点--> <div> </div><!--有1个文本节点--> <div>Hello World!</div>
var textNode = div.firstChild; // div.childNodes[0]div.firstChild.nodeValue = "Some other message";
修改文本节点时需要注意,此时的字符串要经过html编码,也就是说,有些符号会被转译:
//输出结果是"Some <strong>other</strong> message" div.firstChild.nodeValue = "Some <strong>other</strong> message";
创建文本节点:
var textNode = document.createTextNode("<strong>Hello</strong> world!");// 创建文本节点并加入DOM中。var element = document.createElement("div");element.className = "message";var textNode = document.createTextNode("Hello world!");element.appendChild(textNode);document.body.appendChild(element);
规范化文本节点
该方法可以将多个文本节点合并:
var element = document.createElement("div");element.className = "message";var textNode = document.createTextNode("Hello world!");element.appendChild(textNode);var anotherTextNode = document.createTextNode("Yippee!");element.appendChild(anotherTextNode);document.body.appendChild(element);alert(element.childNodes.length); //2element.normalize();alert(element.childNodes.length); //1alert(element.firstChild.nodeValue); // "Hello world!Yippee!"
分割文本节点
该方法的作用和normalize刚好相反,是将一个文本节点分割为多个:
var element = document.createElement("div");element.className = "message";var textNode = document.createTextNode("Hello world!");element.appendChild(textNode);document.body.appendChild(element);var newNode = element.firstChild.splitText(5); alert(element.firstChild.nodeValue); //"Hello"alert(newNode.nodeValue); //" world!"alert(element.childNodes.length); //2
Comment类型
注释用Comment类型表示。特点:
nodeType值为8
nodeName为#comment
nodeValue为注释的内容
parentNode为Document或者Element
没有子节点
<div id="myDiv"><!--A comment --></div>// 访问var div = document.getElementById("myDiv");var comment = div.firstChild;alert(comment.data); //"A comment"// 创建var comment = document.createComment("A comment ");
DocumentType类型
仅有Firefox Safari Opera支持。该类型包含了与文档doctype有关的信息。
nodeType:10
nodeName:doctype的名称
nodeValue:null
parentNode:Document
没有子节点
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">alert(document.doctype.name); //"HTML"
Attr类型
元素的特性在DOM中用Attr类型来表示。
var attr = document.createAttribute("align");attr.value = "left";element.setAttributeNode(attr);alert(element.attributes["align"].value); //"left"alert(element.getAttributeNode("align").value); //"left"alert(element.getAttribute("align")); //"left"
DOM操作技术
动态脚本
使用script元素可以向页面中插入JavaScript代码,一种方式是通过src链接外部文件,另一种方式就是在标签内直接写入代码。
动态脚本,指的是,页面加载时不存在,但是在将来的某一个时刻,通过修改DOM动态添加的脚本。动态创建脚本有两个方式:
1、动态加载外部的JS文件
<script type="text/javascript" src="client.js"></script>
创建这个节点的DOM代码如下所示:
var script = document.createElement("script");script.type = "text/javascript";script.src = "client.js";document.body.appendChild(script);// 函数封装function loadScript(url){ var script = document.createElement("script"); script.type = "text/javascript"; script.src = url; document.body.appendChild(script);}// 加载文件loadScript("client.js");
2、行内方式
<script type="text/javascript"> function sayHi(){ alert("hi"); }</script>// DOM代码 不兼容IEvar script = document.createElement("script");script.type = "text/javascript"; script.appendChild(document.createTextNode("function sayHi(){alert('hi');}")); document.body.appendChild(script);// 兼容IEvar script = document.createElement("script"); script.type = "text/javascript";script.text = "function sayHi(){alert('hi');}"; document.body.appendChild(script);// 函数封装function loadScriptString(code){ var script = document.createElement("script"); script.type = "text/javascript"; try { script.appendChild(document.createTextNode(code)); } catch (ex){ script.text = code; } document.body.appendChild(script);}// 函数调用loadScriptString("function sayHi(){alert('hi');}");
动态样式
<link rel="stylesheet" type="text/css" href="styles.css">// DOM代码var link = document.createElement("link");link.rel = "stylesheet";link.type = "text/css";link.href = "style.css";var head = document.getElementsByTagName("head")[0];head.appendChild(link);// 函数封装function loadStyles(url){ var link = document.createElement("link"); link.rel = "stylesheet"; link.type = "text/css"; link.href = url; var head = document.getElementsByTagName("head")[0]; head.appendChild(link);}// 函数调用loadStyles("styles.css");// 第二种方式<style type="text/css"> body { background-color: red; }</style>// DOM方式var style = document.createElement("style"); style.type = "text/css";try{ style.appendChild(document.createTextNode("body{background-color:red}"));} catch (ex){ style.styleSheet.cssText = "body{background-color:red}";}var head = document.getElementsByTagName("head")[0];head.appendChild(style);// 函数封装function loadStyleString(css){ var style = document.createElement("style"); style.type = "text/css";try{ style.appendChild(document.createTextNode(css));} catch (ex){ style.styleSheet.cssText = css;} var head = document.getElementsByTagName("head")[0]; head.appendChild(style);}// 函数调用loadStyleString("body{background-color:red}");
- JavaScript DOM笔记:修改DOM
- JavaScript DOM 笔记
- JavaScript之DOM笔记
- javascript DOM 学习笔记
- 【javascript】dom学习笔记
- javascript dom学习笔记
- JavaScript学习笔记:DOM
- JavaScript笔记八:DOM
- javascript DOM笔记
- javascript dom学习笔记
- JavaScript DOM事件(笔记)
- JavaScript笔记:DOM
- JavaScript DOM 笔记
- JavaScript DOM笔记
- JavaScript学习笔记---DOM技术
- Javascript DOM学习笔记1
- Javascript DOM学习笔记2
- Javascript DOM学习笔记3
- 这套博客我给满分——All about Keras
- JAVA实践红黑树-小试牛刀
- 找女朋友
- python 学习(十七)之函数
- Using a LotusScript agent to reply to mail from the Internet
- JavaScript笔记:DOM
- HDU5253:连接的管道
- Codeforces Round #352 (Div. 2) C. Recycling Bottles (几何)
- Android开发之Intent.Action
- 数据结构实验之排序一:一趟快排
- 199.leetcode Binary Tree Right Side View(medium)[层次遍历二叉树 队列]
- Exception loading sessions from persistent storage
- 【Dongle】【JavaScript】getElementsByTagName
- 从尾到头打印链表