- HTML元素特性与DOM属性
- Element类型节点
- Text类型节点
HTML元素特性与DOM属性
HTML标签中的attribute和DOM对象的property是比较容易混淆的两个概念,实际上这二者对于理解”文档对象模型”是十分重要的。通常我们会把HTML标签的attribute译为”特性”而把DOM对象的property译为”属性”。
文档对象模型(DOM)是针对HTML和XML文档的一个API。DOM描绘了一个层次化的节点树,它允许我们通过DOM添加、移除以及修改页面的某一部分。
实际上这里面就包含了2个概念,一个是HTML页面,另一个是DOM对象模型。
我们举例来说:
<div id="div1" class="bd" title="Body text">...</div>
以上是一个HTML元素。其中的”id”,”class”,”title”都是该元素的特性(attribute)。我们希望能够通过JS来访问、删改该div的这些特性怎么办?在JS中我们可以通过DOM来取得对应元素的引用:
var div1 = document.getElementById("div1");
注意,这里的div1是对一个JS对象的引用。该对象中包含”id”,”className”,”title”等属性(property)。它们分别和HTML中div元素的”id”,”class”,”title”特性相对应。通常情况下,它们的名字是相同的。例如”id”和”id”对应,”title”和”title”对应。但这里,由于class是JS中的保留字,所以去”calssName”对应于div元素的”calss”特性。
我们可以通过div1对象中的对应属性或者getAttribute、setAttribute、removeAttitude方法来访问删改HTML元素中的特性值。但需要注意的是,元素特性和DOM对象属性是两个不同的概念。
HTML中每一种元素都对应DOM中一种HTMLXXXElement接口,该接口继承自HTMLElement,而HTMLElement接口又直接继承于Element,同时Element接口又继承自Node。
Element类型节点
Element类型节点在Web编程中十分常用。内容较多,分为以下部分:
- 元素标签名的获取
- HTML元素特性的操作方法
- Element类型节点的attributes属性
- 元素的创建
元素标签名的获取
在Node类型中定义的12种节点类型中,Element类型属Node.ELEMENT_NODE,对应数值1。基本特征如下:
- nodeType值为1
- nodeName值为元素标签名
- nodeValue值为null
我们要获取元素的标签名可以直接通过nodeName属性获得,例如:
<div id="div1" class="bd" title="Body text">...</div>
...
var div1 = document.getElementById("div1");
var tag1 = div1.nodeName;
另外,也可以通过tagName属性获得,二者返回值是完全一样的:
var tag2 = div1.tagName; // tag1 == tag2
唯一需要注意的是,在HTML中,元素的标签名始终为大写:
alert(tag1); // DIV
而在XML中标签名会和源代码中保持一致,因此为了确保代码在HTML和XML中的兼容性,我们在操作标签名之前最好进行统一的大小写转换:
if(element.tagName.toLowerCase() == "div") { ... }
HTML元素特性的操作方法
- 1通过DOM属性访问元素特性
- 2通过getAttribute方法访问元素特性
- 3通过setAttribute方法设置元素特性
- 4通过removeAttribute方法删除元素特性
1通过DOM属性访问元素特性
在DOM中,所有的HTML元素都对应着一个HTMLElement接口或其子接口。作为示例,我们列举几个常用的元素的对应关系:
HTML元素 | DOM接口 |
---|---|
H1~H6 | HTMLHeadingElement |
FORM | HTMLFormElement |
DIV | HTMLDivElement |
CITE | HTMLElement |
P | HTMLParagraphElement |
在与HTML元素对应的DOM对象中,包含着与HTML元素特性对应的属性,我们以div元素为例,列出几个基本特性:
DIV元素特性 | DOM属性 |
---|---|
id | id |
title | title |
dir | dior |
class | className |
… | … |
再次强调,由于class是JS中的保留字,故与HTML元素中class特性对应的属性名为className。
我们可以通过DOM属性直接访问修改对应的HTML特性:
<div id="div1" class="bd" title="Body text">...</div>
...
var div1 = document.getElementById("div1");
div1.di = ‘newdiv‘;
div.className = "newbd";
div.title = "newTitle";
所有HTML元素的所有特性,都可以通过DOM元素本身的属性来访问。只有一个例外,自定义特性。自定义特性不会以属性的形式添加到DOM对象中:
<div id="div1" class="bd" data-myAttr = "easy">...</div>
...
var div1 = document.getElementById("div1");
alert(div1.data-myAttr); //VM226:1 Uncaught ReferenceError: myAttr is not defined(…)
但是自定义属性可以通过getAttribute方法来获取,后面会说到。
2通过getAttribute方法访问元素特性
我们除了可以通过属性的方式访问元素的特性,DOM对象还为我们提供了getAttribute方法来获取特性值。getAttribute接收1个参数,即要访问的特性的名称,如果该特性不存在会返回null:
<div id="div1" class="bd" title="Body text">...</div>
...
var div1 = document.getElementById("div1");
alert(div1.getAttribute("id")); //div1
alert(div1.getAttribute("class")); //bd
alert(div1.getAttribute("title")); //Body text
强调一点,在使用getAttribute方法的时候,元素中特性的名称是什么,我们就传入对应的参数,包括在属性访问中例外的”class”。另外, getAttribute方法也可以访问我们的自定义特性:
<div id="div1" class="bd" data-myAttr = "easy">...</div>
...
var div1 = document.getElementById("div1");
alert(div1.data-myAttr); //easy
注意,根据HTML5规范,自定义特性应加上data-前缀以便验证。
3通过setAttribute方法设置元素特性
setAttribute可以用来为元素设置特性值。该方法接收2个参数,第一个为要设置的特性名,第二个为待设置的值。注意,如果要设置的特性不存在,该方法会创建并设置相应的值。用法很简单:
<div id="div1" class="bd" title="Body text">...</div>
...
var div1 = document.getElementById("div1");
div1.setAttribute("id", "newvid");
div1.setAttribute("class", "newbd");
div1.setAttribute("title", "newTitle");
div1.setAttribute("dir", "rtl"); //设置新特性!
另外,setAttribute方法可以设置自定义特性:
div1.setAttribute("data-myAttr", "easy");
alert(div1.getAttribute("data-myAttr")); //easy
如果直接使用属性的方法来添加自定义特性,该属性是不会成为元素的特性的,虽然它会存在于DOM的属性中:
div1.data-myAttr = easy;
alert(div1.getAttribute("data-myAttr")); //null
alert(div1.data-myAttr); //easy
实际上div1.data-myAttr = easy
只不过相当于我们在一个普通的JavaScript对象中添加了一个属性罢了。
另外,虽然getArrtibute和setAttribute不区分大小写,但本人认为这并不是一个好的习惯,我们在书写的时候,最好各方保持一致。
4通过removeAttribute方法删除元素特性
该方法用于彻底删除元素的特性,方法接收一个参数,即要删除的元素特性的名称。
div1.removeAttrubute("title");
Element类型节点的attributes属性
HTML元素的每一个特性都保存在节点对象attributes属性指向的NamedNodeMap对象中。还记得Node中定义的12种节点类型吗?可以参考JavaScript DOM(一)。在NamedNodeMap中,每一个HTML元素特性都保存为一个Node.ATTRIBUTE_NODE(对应数值2)类型的节点。我们以下面的代码为例:
<ul id="list1">
<li class="fruit" name="li1">Apple</li>
<li class="fruit" name="li2">Watermelon</li>
<li class="fruit" name="li3">Pear</li>
<li class="fruit" name="li4">Orange</li>
</ul>
我们取得ul元素的attributes属性指向的NamedNodeMap,其中包含2个节点:
0: id
1: class
它们都是Node.ATTRIBUTE_NODE类型节点:
元素的创建
在DOM中,我们可以使用document.createElement()方法来创建新元素。该方法接收一个参数,即要创建的新元素的标签名。需要注意的是,在调用该方法创建元素之后,新元素并没有被添加到文档树中,我们可以调用JavaScript DOM(一)中介绍的appendChild、insertBefore或replaceChild方法将新建的元素添加到文档树中,以便在浏览器中呈现该元素。例如对以下HTML代码:
<body>
<h2>Nice Fruit</h2>
<p title="A list of fruit">Eat them usually.</p>
<ul id="list1" class="ul">
<li class="fruit" name="li1">Apple</li>
<li class="fruit" name="li2">Watermelon</li>
<li class="fruit" name="li3">Pear</li>
<li class="fruit" name="li4">Orange</li>
</ul>
</body>
执行以下JS代码:
var myh2 = document.createElement("h2");
var mytext = document.createTextNode("Nice Candy");
myh2.appendChild(mytext);
document.body.appendChild(myh2);
便会在HTML页面中添加一个”Nice Candy”的h2标题。
另外要说明的是,通过document.createElement()方法创建新元素的同时,该元素的ownerDocument属性同时也被指定为当前文档了。
Text类型节点
以上介绍的Element类型节点只是12种类型中的一种。文档中,Element类型节点通常提供的是一个结构,并不会包含太多内容。内容在绝大所数时候是由文本提供的。文本节点总是被包含在元素节点内部,但并不是所有元素节点都包含文本节点。
- 文本节点基本特征
- 文本节点的创建
- 操作节点文本的方法
文本节点基本特征
有关节点的基本信息我们可以通过其nodeType、nodeName以及nodeValue属性提供。文本节点中,nodeType值为3,nodeName为”#text”,nodeValue即其所包含的具体文本。
我们可以通过nodeValue属性来访问文本的具体内容,为了直观起见,我们也可以通过data属性来访问文本节点的具体文本内容。二者包含相同的值。对其中任何一个属性的修改会在相应另一属性上反映出来。
文本节点的length属性中保存着节点字符的数目。同样地,我们可以通过myText.nodeValue.length
或者myText.data.length
来访问该属性,二者保存相同的值。
以下代码为例:
<p title="A list of fruit" id="p1">Eat them usually.</p>
文本节点的创建
创建文本节点可以使用createTextNode方法,该方法接受一个参数,用于表示创建节点的文本内容:
document.createTextNode("Hello World! <This is a nice world!>");
以上例子中有以下几点需要注意:
- 1、文本节点的内容是纯文本内容,不能包含HTML代码。文本节点的字符串会自动经过HTML编码。其中的大于号,小于号以及引号会被转义。上例的文本内容会被转义如下:
"Hello World! <This is a nice world!>"
- 2、文本节点创建的同时,其ownerDocument属性会被自动指定为当前文档;
- 3、同createElement方法,新创建的Text节点,需要通过appendChild、insertBefore、replaceChild等方法添加到DOM树中才会被浏览器显示;
- 4、通常情况下,每个可包含文本节点的元素最多只包含1个文本节点,且该节点必须有内容存在。如果我们为一个元素节点创建了多个文本子节点,则这些文本节点在显示的时候会连起来显示,中间不会留有空格,它们彼此互为同胞结点。但在DOM文档中存在相邻同胞文本节点很容易导致混乱,我们可以通过normalize()方法将相邻文本节点合并。
同样以上面的代码为例:
<body>
<h2>Nice Fruit</h2>
<p title="A list of fruit" id="p1">Eat them usually.</p>
<ul id="list1" class="ul">
<li class="fruit" name="li1">Apple</li>
<li class="fruit" name="li2">Watermelon</li>
<li class="fruit" name="li3">Pear</li>
<li class="fruit" name="li4">Orange</li>
</ul>
</body>
操作节点文本的方法
这些方法的使用和字符串操作类似,在此备忘,不再举例。
- appendData(text):将text添加在文本末尾;
- deleteData(offset, count):从offset处开始删除count个字符;
- insertData(offset, text):在offset处插入text;
- replaceData(offset, count, text):用text替换offset起的count个字符;
- splitText(offset):从offset位置切分文本,返回offset到文本末尾的新节点;