JavaScript DOM(二)

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编程中十分常用。内容较多,分为以下部分:

元素标签名的获取

在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属性访问元素特性

在DOM中,所有的HTML元素都对应着一个HTMLElement接口或其子接口。作为示例,我们列举几个常用的元素的对应关系:

HTML元素DOM接口
H1~H6HTMLHeadingElement
FORMHTMLFormElement
DIVHTMLDivElement
CITEHTMLElement
PHTMLParagraphElement

在与HTML元素对应的DOM对象中,包含着与HTML元素特性对应的属性,我们以div元素为例,列出几个基本特性:

DIV元素特性DOM属性
idid
titletitle
dirdior
classclassName

再次强调,由于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! &lt;This is a nice world!&gt;"
  • 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到文本末尾的新节点;
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值