JavaScript在Web开发中的主要作用是与用户交互,在网页上添加某种行为。JavaScript允许在网页加载到浏览器中后,完全改变网页的所有方面,JavaScript在网页上提供这个功能的基础是文档对象模型(Document Object Model,DOM),这是网页的树状表示方法。DOM为开发人员提供了一种表示网页中的所有元素的方式,以便在JavaScript中通过一组通用的属性和方法来访问。通过JavaScript修改相应的DOM属性,就能修改页面中的图形,表格,表单,样式,甚至文本自身。
DOM模型与BOM模型是两个不同的概念。目前可以将BOM视为一个代表浏览器各种特性的依赖浏览器的对象,包括浏览器的按钮,URL地址栏,标题栏,浏览器窗口空间以及网页的各部分。而DOM仅处理浏览器窗口或网页(即HTML文档)中的内容,任何浏览器都可以使用完全相同的代码来访问和操作文档的内容。
DOM与浏览器和平台无关,开发人员可以使用JavaScript代码动态更新页面,这些代码在任何兼容DOM的浏览器上都能正常运行,无须做任何修改。DOM将页面的内容表示为通用的树结构,实现了这种无关性。在BOM中访问某个对象时,需要查找与该浏览器部分相关的属性。而DOM只需要在页面的树型结构中导航到与浏览器无关的节点或属性上。
文档对象模型
文档对象模型(DOM)是一种独立于浏览器类型来表示文档的方法。它允许开发人员通过一组通用的对象,属性,方法和事件来访问文档,并通过脚本动态修改网页内容。W3C以DOM标准的形式提供了一组可用于所有浏览器的通用对象,属性和方法。
- DOM和BOM的区别
文档对象模型(DOM)和浏览器对象模型(BOM)之间存在两个主要的区别。
1.DOM仅包含Web页面的文档,而BOM提供了浏览器各个领域的脚步编程访问,包括按钮,标题栏以及页面的某些部分。
2.BOM专用于某个浏览器。 - HTML文档的树型结构
Html是标准化的,因此网页只能包含HTML语言支持的特性,如表单,表格和图片等,且需要一种通用的方法,来访问这些特性。此时需要使用DOM,它提供了HTML文档的统一表达方式,即将整个HTML文档/网页表示为树型结构。实际上,可以将任何HTML表示为树型结构。通过DOM访问元素的能力,取决于将页面表示为层次结构的能力。
树型结构是表示层次结构的一种图标方式,以层次方式导航DOM比使用完全线性的方法有意义。DOM中的树型结构如下所示:
-
树的顶层是文档和包含页面中所有其他元素的元素,文档就是根节点。节点只是树中的一个点,表示某个元素,元素的属性或特性,或者元素包含的文本。根节点包含了所有的其他节点,如DTD声明以及根元素(包含所有其他元素的HTML或XML元素)。在HTML文档中,根元素应总是<html>元素。在根元素之下,是根元素包含的HTML元素。HTML页面一般在<html>元素中包含<head>和<body>元素。这些元素表示为根元素节点下的节点,而根元素节点本身在树顶部的根节点之下。
DOM核心对象
DOM提供了一组具体的对象,属性和方法,通过JavaScript可以访问它们,以便浏览DOM的树型结构。
- 基本DOM对象
-
对象 说明 Node 文档中的每个节点都有自己的Node对象 NodeList 这是Node对象的列表 NamedNodeMap 允许按名称(而不是按索引)访问所有Node对象 有了基本的DOM对象,就可以在网页文档中添加,替换或移除网页的各个部分,而不会影响整个页面的结构,因为只是改变了树型结构中的节点。实际上,有不同的对象表示树中不同类型的节点。
- 高级DOM对象
DOM中的所有东西都是节点,所以节点肯定有各种类型。Node对象有不同的子对象,来表示每种类型的节点。DOM中三种主要的节点类型,即元素,属性和文本。 -
对象 说明 Document 文档的根节点 DocumentType XML文档的DTD或模式类型 DocumentFragment 文档部分的临时存储空间 EntityReference XML文档中的实体引用 Element 文档中的一个元素 Attr 文档中元素的一个属性 ProcessingInstruction 处理指令 Comment XML文档或HTML文档中的注释 Text 构成元素子节点的纯文本 CDATASection XML文档中的CDATA部分 Entity DTD中未解析的实体 Notation DTD中声明的记号 这些对象都继承了Node对象的所有属性和方法,还包含了自己的一些属性和方法。
这些介绍三个主要的对象Node,Element和Document,通过这三个对象,就可以创建,修改和导航树型结构。
Document对象及其方法
Document对象提供的方法允许查找单个元素或元素组,创建新元素,属性和文本节点。只有Document对象的方法可以在页面上查找,创建和删除元素。
- 查找一个或多个元素
-
document对象的方法 说明 getElementById(idValue) 根据所提供的元素的id值,返回对该元素的引用(节点) getElementByTagName(tagName) 根据参数中提供的标记,返回对一组元素的引用(节点列表) querySelector(cssSelector) 返回与给定CSS选择器匹配的第一个元素的引用(节点) querySelectorAll(cssSelector) 返回与给定CSS选择器匹配的一组元素的引用(节点列表) 第一个方法getElementById()要求确保在页面中快速访问的每个元素都使用id属性,否则该方法返回null(表示缺失或未知的值)。可以使用该方法,返回一个对页面上带id属性的任意HTML元素的引用。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1 id="heading1">My Heading</h1> <p id="paragraph1">This is some text in a paragraph</p> <script> alert(document.getElementById("heading1").innerText); var h1Element=document.getElementById("heading1"); h1Element.style.color="red"; </script> </body> </html>
第二个方法getElementsByTagName参数是放在引号中的元素名,例如可以是表单元格”td”,超链接元素”a”等等。该方法只返回一个对象,但是该对象是一个元素集合。集合类似于数组,可以通过索引号来访问集合中的特定元素,可以使用方括号来指定,也可以使用NodeList独享的item()方法。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1"> <tr> <td>Row 1 Cell 1</td> </tr> <tr> <td>Row 1 Cell 2</td> </tr> </table> <script> var tdElement=document.getElementsByTagName("td").item(0); tdElement.style.color="green"; </script> </body> </html>
上述代码将第一个表单元格的字体颜色设置为绿色。
第三个方法querySelector()用于获取匹配所提供CSS选择器的第一个元素,它可以方便地获取没有id属性的元素。
例如下面的HTML:<p class="sub-title">This is a <span>special</span> paragraph element that contains <span> some text </span> </p>.
使用querySelector()方法可以使用如下代码获取这个HTML中的第一个<span/>元素。
var firstSpan=document.querySelector(".sub-title span");
所提供的CSS选择器匹配包含在父元素中,CSS类为sub-title的所有<span/>元素。
- 创建元素和文本
-
document对象的方法 说明 createElement(elementName) 使用指定的标记名创建一个元素节点,返回所创建的元素 createTextNode(text) 创建并返回包含所提供文本的文本节点 下面的代码创建了一个文本节点和一个h1元素。
var nextText=document.createTextNode("New Text"); var newElem=document.createElement("h1");
- Document对象的属性:获取文档的根元素
树型结构包含页面上所有的元素和节点,并将它们放在一个层次结构中。如果要引用这个结构,需要使用document对象的一个特殊属性,该属性返回文档的最外层元素。在HTML中,它总是<html/>元素。返回这个元素的属性是documentElement。documentElement属性以对象的形式返回对这个元素的引用,确切地是Element对象。 -
var container=document.documentElement; alert(container.tagName);
上面的代码会在一个信息框中显示Html。
Element对象
Element对象常用属性和方法:
Element属性 说明 tagName 获取元素的标记名称 getAttribute(attributeName) 返回所提供的属性的值;如果该属性不存在,就返回null或空字符串 setAttribute(attributeName,value) 用指定的值设置属性 removeAttribute(attributeName) 从元素中删除指定的属性及其值 ,代之以默认值 例如下面的代码设置文本的位置:
<html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1 id="heading1">My Heading</h1> <p id="paragraph1">This is some text in a paragraph</p> <script> var h1Element=document.getElementById("heading1"); h1Element.setAttribute("align","center"); alert(h1Element.getAttribute("align")); h1Element.removeAttribute("align"); </script> </body> </html>
Node对象
从网页中获取了元素后,如果要遍历元素,属性和文本,需要沿着树型结构的节点移动。至于节点包含什么内容,甚至节点是什么类型,都无关紧要。因此需要使用DOM核心规范的一个对象Node,整个树型结构都是由这些基本的Node对象构成。
- Node属性
如下表列出了Node对象的常用属性,这些属性提供了节点的信息,即当前节点是元素,属性还是文本,并可以从一个节点移动到另一个节点。 -
Node对象的属性 说明 firstChild 返回元素的第一个子节点 lastChild 返回元素的最后一个子节点 previousSibling 在同级子节点中,返回当前子节点的前一个兄弟节点 nextSibling 在同级子节点中,返回当前子节点的后一个兄弟节点 ownerDocument 返回包含节点的文档的根节点 parentNode 返回属性结构中包含当前节点的元素 nodeName 返回节点的名称 nodeType 返回一个数字,表示节点的类型 nodeValue 以纯文本格式获取或设置节点的值 例如下面的代码显示heading1节点的下一个兄弟节点
var h1Element=document.getElementById("heading1"); h1Element.style.color="red"; alert(h1Element.nextElementSibling.nodeType);
- Node对象方法
Node对象的属性可以导航DOM,而其方法提供了完全不同的功能:在DOM中添加和删除节点,从根本上改变了HTML文档的结构。 -
Node对象的方法 说明 appendChild(newNode) 将一个新node对象添加到子节点列表的末尾;该方法返回追加的节点 cloneNode(cloneChildren) 返回当前节点的一个副本;该方法的参数是一个布尔值,如果该值为true,则克隆当前节点及其所有的子节点;如果该值为false,则仅克隆当前节点,而不包含其子节点 hasChildNodes() 如果节点有子节点,则返回true,否则返回false insertBefore(newNode,referenceNode) 在referenceNode指定的节点前,插入一个node对象,返回新插入的节点 removeChilde(childNode) 从node对象的子节点列表中,删除一个子节点,并返回删除的节点 例如下面的代码使用DOM方法创建HTML元素和文本,并添加到文档末尾:
var nextText=document.createTextNode("New Text"); var newElem=document.createElement("h1"); newElem.appendChild(nextText); document.body.appendChild(newElem);
操作DOM
DHTML是浏览器加载HTML页面后,操纵该页面的技术。
- 改变元素的外观
改变页面元素的外观,主要指的是改变HTML元素的CSS属性。在JavaScript中,有两种方式:
1.使用style属性改变各个CSS属性
要修改特定的CSS属性,必须使用style属性。所有浏览器都实现了这个对象,该对象直接映射到元素的style属性。style对象包含CSS属性,使用该对象,可以修改浏览器支持的任何CSS属性。
CSS属性名通常匹配CSS样式表使用的名称,例如改变元素文本颜色,可使用color属性: -
var divAdvert=document.getElementById("divAdvert"); divAdvert.style.color="blue";
对于包含连字符(-)的CSS属性,需要去掉连字符,并把连字符后的第一个字母改成大写,例如:
divAdvert.style.backgroundColor="gray";
可以使用style对象来获取声明的样式,如果要获取的style属性没有用style属性(即内联样式)或style对象设置,则不能获取属性的值。例如下面的代码包含一个样式表和</div>元素:
<style> #divAdvert{ background-color:gray; } </style> <div id="divAdvert" style="color: green">Test</div> <script> var divAdvert=document.getElementById("divAdvert"); alert(divAdvert.style.backgroundColor);//提示 空 字符串 alert(divAdvert.style.color);//提示 green </script>
当浏览器显示这个元素时,会显示灰底绿字。但是获取backgroundColor时得到空字符串,获取color时得到green值,是由于style对象直接映射到元素的style属性上。如果在<style/>块中设置样式声明,或在外部样式表中声明,则不能通过style对象来获取该属性的值。
2.修改元素的class属性值
使用元素的class属性可以把CSS类赋予元素。在DOM中,该属性通过className属性来使用,可以通过JavaScript修改className属性,为元素应用另一个样式规则。element.className=sNewClassName;
使用className属性来修改元素样式具有两个优点,一是减少了需要编写的JavaScript代码量,二是可将样式信息从JavaScript文件中提取出来,放在它所属的CSS文件中。
例如下面的代码给divAdvert元素采用了新的样式规则,浏览器就会改变其显示方式:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #divAdvert{ font:20pt arial; } .new-style{ font-style: italic; text-decoration: underline; } </style> </head> <body> <div id="divAdvert"> Here is an advertisement. </div> <script> var divAdvert=document.getElementById("divAdvert"); divAdvert.className="new-style"; </script> </body> </html>
- 定位和移动内容
DOM脚本编程不仅能改变元素在页面上的显示方式,还可以通过JavaScript改变元素的位置。
在JavaScript中移动内容,可以使用position属性来改变所需位置的类型,使用left和top属性可以定位元素。 -
例如下面的代码把position属性设置为绝对位置,把元素移动到距离左边界和上边界各100像素的地方。
divAdvert.style.position="absolute"; divAdvert.style.left="100px"; divAdvert.style.top="100px";
注意:必须在设置位置值时指定单位,否则,浏览器将无法定位该元素。