js高级程序设计笔记6--DOM

这篇笔记详细介绍了JavaScript中的DOM操作,包括Node类型的节点类型、操作方法,如appendChild和removeChild,以及Document和Element类型的相关属性和方法。特别讨论了如何查找元素,如getElementById、getElementsByTagName和getElementsByClassName,以及动态脚本和样式的操作。此外,还涵盖了Text、Comment、Attr等特殊类型的节点,以及如何处理表格和NodeList对象。
摘要由CSDN通过智能技术生成

Node类型

DOM1级定义了一个Node接口,该接口将由DOM中的所有节点类型实现。因此所有节点类型都共享这相同的基本属性和方法。每个节点类型都有一个nodeType属性,用于表明节点的类型。由12个数值常亮来表示。

Node.ELEMENT_NODE(1);
Node.ATTUIBUTE_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 == Node.ELEMENT_NODE){//在IE中无效
    alert("node is an element");
}
//IE没有公开Node类型的构造函数
if(someNode.nodeType == 1){//所有浏览器适用
    alert("node is an element");
}

并不是所有节点类型都受到web浏览器的支持,开发人员最常用到的是元素和文本节点。

  1. nodeName保存的是元素的标签名,而nodeValue的值则始终为null.
if(someNode.nodeType == 1){
    value = someNode.nodeName;
}

节点类型

每个节点都有一个childNodes属性,其中保存着一个NodeList对象。NodeList是一种类数组对象,用于保存一组有序的节点,但他不是Array的实例。他实际上是基于DOM结构动态执行查询的结果。因此DOM结构的变化能够自动反映在NodeList对象中。
访问NodeList中的节点:

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);//IE8及更早版本无效
    }catch(ex){
        array = new Array();
        for(var i=0,len=nodes.length;i<len;i++){
            array.push(nodes[i]);
        }
    }
    return array;
}

每个节点都有一个parentNode属性,指向文档树中的父节点。包含在childNodes列表中的每个节点相互之间都是同胞节点。通过previousSibling和nextSibling属性访问前后兄弟节点。

父节点的firstChild和lastChild分别指向childNodes列表中的第一个和最后一个节点。

hasChildNodes()方法判断有没有子节点。
所有节点还有一个属性ownerDocument,指向表示整个文档的文档节点。

操作节点

appendChild():新增节点并返回新增的节点。

var returnedNode =someNode.appendChild(newNode);
alert(returnedNode == newNode);//true

如果传入到appendChild中的节点已经是文档的一部分,那么就会将该节点从原来的位置转移到新位置。任何DOM节点不能同时出现在文档中的多个位置上。

insertBefore(要插入的节点,参照节点):返回新插入的节点。如果第二个参数为null,则与appendChild()执行相同的操作。
replaceChild(要插入的节点,要替换的节点):返回要替换的节点。
removeChild(要移除的节点):返回要移除的节点。

其他方法

有两个方法是所有类型的节点都有的。
cloneNode():创建调用这个方法的节点的一个完全相同的副本。接收一个布尔值参数,表示是否执行深复制。true表示执行深复制,复制节点及整个子节点树。false表示只复制节点本身。复制后的返回的节点属于文档所有,但并没有为它指定父节点。要通过appendChild().insertBefore()等方法将它添加到文档中。
注:cloneNode()方法不会复制添加到DOM节点中的javascript属性,例如事件处理程序。这个方法只复制特性。
normalize():处理文档树中的节点。如果该节点的后代节点中有空文本节点,则删除它,如果找到相邻的文本节点,则将他们合并成一个文本节点。

Document类型

Document类型表示文档。nodeType的值为9,nodeName的值为“#document”.可以表示HTML页面或其他基于XML的文档。

var html = document.documentElement;//取得对<html>的引用
alert(html === document.childNodes[0]);//true
alert(html === document.firstChild);
var body = document.body;//取得对<body>的引用
var doctype = document.doctype;//取得对<!DOCTYPE>的引用。不同浏览器差异很大。很少使用

多数情况下不必在document对象上调用appendChild(),removeChild()等方法。因为文档类型是只读的。而且它只能有一个元素子节点。

文档信息

作为HTMLDocument的一个实例,document对象还有一些标准的Document对象所没有的属性。

var orginanlTitle = document.title;//取得文档标题
document.title = "new page title";

与网页请求相关的3个属性,这些属性都保存在请求的HTTP头部。
URL:即地址栏中显示的URL
domain:页面的域名
referrer:链接到当前页面的那个页面的URL。即来源URL。

var url = document.URL;
var domain = document.domain;
var referrer = document.referrer;

这三个属性只有domain是可以设置的。且只能设置为原URL中包含的一个子域名。例如p2p.wrox.com只能将domain设置为wrox.com。

查找元素

  • getElementById(“id”):如果页面中多个元素的ID值相同,则只返回文档中第一次出现的元素。
    IE7及最早版本有个“怪癖”:name特性与给定ID匹配的表单元素(input,textarea)也会被该方法返回。而且该元素在文档中位于给定ID的元素前面,那么IE就会返回那个表单元素。
<input type="text" name="mydiv" value="text field">
<div id="mydiv">a div</div>

在IE7中调用document.getElementById(“mydiv”)会返回元素。

  • getElementsByTagName(标签名):返回包含零或多个元素的NodeList。在HTML文档中,这个方法会返回HTMLCollection对象。该对象与NodeList对象类似,
var images = document.getElementsByTagName("img");
alert(images.length);
alert(images[0].src);//后台执行等于下面这句
alert(images.item(0).src);
//可以通过namedItem()方法取得集合中特定name的项
var myImage = images.namedItem("myImage");
var myImage = images["myImage"];//后台执行等于上面这句

为了与既有HTML兼容,传给getElementsByTagName的标签名是不区分大小写的。

  • getElementsByName():返回带有给定name特性的所有元素。最长使用此方法的情况是取得单选按钮。该方法也是返回一个HTMLColection对象。

特殊集合

document对象还有一些特殊的集合。这些集合都是HTMLCollection对象
document.anchors:包含文档中所有带有name特性的元素。
document.applets:包含文档中所有元素。不建议使用
document.forms:包含文档中所有元素。
document.images:包含文档中所有元素。
docuemnt.links:包含文档中所有带href特性的元素

文档写入

将输出流写入到网页中。
write():
writen():
open():打开网页的输出流
close():关闭网页的输出流
动态包含外部文件:

<script type="text/javascript">
    document.wirte("<script type=\"text/javascript\" src=\"file.js\">"+
"<\/script>");
</script>

Element类型

用于表现XML或HTML元素。提供了对元素标签名、子节点及特性的访问。具有如下特性:
nodeType值为1,nodeName的值为元素的标签名。

var div = document.getElementById("mydiv");
alert(div.tagName);//"DIV"
alert(div.tagName == div.nodeName);//true

HTML元素

所有HTML元素都由HTMLElement类型表示。HTMLElement类型继承自Element类型并添加了一些属性。
id:元素在文档中的唯一标识符
title:有关元素的附加说明信息。一般通过工具提示条显示出来。
lang:元素内容的语言代码,很少使用。
dir:语言的方向。“ltr”表示从左至右,”rtl”表示从右至左。很少使用。
className:与元素的class特性对应。

<div id="mydiv" class="bd" title="body text" lang="en" dir="ltr"></div>

还有三个方法,用于操作HTMLElement属性:
getAttribute():得到特定属性值
setAttribute():设置某个属性值
removeAttribute():删除属性

var mydiv = document.getElementById("mydiv");
div.setAttribute("class","ft");
div.getAttribute("id");
div.removeAttribute("class");

attributes属性

Element类型是使用attributes属性的唯一一个DOM节点类型,它包含一个NamedNodeMap对象,该对象拥有以下方法:
1. getNamedItem(name):返回nodeName属性等于name的节点。
2. removeNamedItem(name):移除nodeName属性等于name的节点
3. setNamedItem(node):向列表中添加节点。
4. item(pos):返回位于数字pos位置处的节点。

var id = element.attributes.getNamedItem("id").nodeValue;
var id = element.attributes["id"].nodeValue;

以上方法不常用,不过在遍历元素特性时可以用到。

var outputAttributes(element){
    var pairs = new Array(),
        attrName,
        attrValue,
        i,
        len;
    for(i=0,len=element.attributes.length;i<len;i++){
        attrName = element.attributes[i].nodeName;
        attrValue = element.attributes[i].nodeValue;
        //让它只返回指定的特性即html中指定的相应特性或者通过setAttribute()设置了该特性
        if(element.attributes[i].specified){
            pairs.push(attrName = "=\"" = attrValue + "\"");
        }
    }
    return pairs.join(" ");
}

创建元素

var div = document.createElement("div");
div.id="myNewDiv";
div.className = "box";
document.body.appendChild(div);

在IE7中可以使用另一种方式

var div = document.createElement("<div id=\"myNewDiv\" class=\"box\"></div>");
if(client.browser.ie && client.browser.ie<=7){
    var iframe = document.createElement("<iframe name=\"myframe\"></iframe>");
    var input = document.createElement("<input type=\"checkbox\">");
    var button = document.createElement("<button type=\"reset\"></button>");
    var radio1= document.createElement("<input type=\"radio\" name=\"choice\" value=\"1\">");
    var radio2= document.createElement("<input type=\"radio\" name=\"choice\" value=\"2\">");
}

元素的子节点

<ul id="mylist">
    <li>item1</li>
    <li>item2</li>
    <li>item3</li>
</ul>

在IE中,

  • 元素有3个子节点,分别是3个
  • 元素。在其他浏览器中,
    • 元素会有7个元素:3个
    • 元素4个文本节点(表示
    • 元素之间的空白符)。如果像下面这样将元素间的空白符删除。那么所有浏览器都会返回相同数目的子节点。

<ul id="mylist"><li>item1</li><li>item2</li><li>item3</li></ul>

在遍历这些子节点的属性时,通常先检查下nodeType属性。

for(var i=0,len=element.childNodes.length;i<len;i++){
    if(element.childNodes[i].nodeType == 1){//表示元素节点
        //do something
    }
}

Text类型

包含的是可以照字面解释的纯文本节点。纯文本中可以包含转义后的HTNL字符,但不能包含HTML代码。
Text节点具有以下特征。
nodeType的值为3.
nodeName的值为“#text”;
nodeValue的值为节点所包含的文本。
可以通过nodeValue属性或data属性访问Text节点中包含的文本。使用下列方法可以操作节点中的文本。
appendData(text):将text添加到节点的末尾。
deleteData(offset,count):从offset指定的位置开始删除count个字符。
insertData(offset,text):在offset指定的位置插入text.
repalaceData(offset,count,text):用text替换从offset指定的位置开始到offset+count为止处的文本。
splitText(offset):从offset指定的位置将当前文本分成两个文本节点。
subStringData(offset,count):提取从offset指定的位置开始到offset+count为止处的字符串。

  1. document.createTextNode(文本):创建文本节点.
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类型

注释在DOM中是通过Comment类型来表示的。具有如下特征:
nodeType的值为8;nodeName的值为#comment。nodeValue是注释的内容。
Comment类型与Text类型继承自相同的基类,因此他拥有splitText()之外的所有字符串操作方法。也可以通过nodeValue或data属性来取得注释的内容。

<div id="mydiv"><!--A comment --></div>

var div = document.getElementById("mydiv");
var comment = div.firstChild;
alert(comment.data);// A comment

document.createComment(“comment”):创建注释节点

CDATASection类型

此类型只针对XML文档,表示的是CDATA区域。与Comment类似,CDATASection类型继承自Text类型,因此拥有除splitText()之外的所有字符串操作方法。
CDATA区域只会出现在XML文档中,因此多数浏览器都会把CDATA区域错误的解析为Comment或Element.

<div id="mydiv"><![CDATA[This is some content.]]</div>

四大主流浏览器不能正确的解析CDATASection节点。在真正的XML文档中,可以使用document.createCDataSection()来创建CDATA区域。

Attr类型

元素的特性用Attr类型来表示。此类型有3个属性,name,value,speciied(区别特性是在代码中指定的还是默认的)
document.createAttribute()可创建新的特性节点

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动态添加的脚本。有两种方式:插入外部文件和直接插入javascript代码。

<script type="text/javascript" src="client.js"></srcript>

整个过程可以用以下函数来表示。

function landScriptString(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);
}

以这种方式加载的代码会在全局作用域中执行。相同于将字符串传递给eval()是一样的。

动态样式

所谓动态样式是指在页面加载完后动态添加到页面中的。

<link rel="stylesheet" type="text/css" href="styles.csss">

动态样式加载过程如下函数所示:

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}";//针对ie
}
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);

操作表格

元素的属性和方法:

caption:保存着对元素的指针
tBodies:是一个元素的HTMLCollection.
tFoot:保存着对元素的指针
tHead:
rows:是一个表格中所有行的HTMLCollection.
createTHead():创建元素,将其放到表格中,返回其引用。
createTFoot():
createCaption():
deleteTHead():
deleteTFoot():
deleteRow(pos):删除指定位置的行
insertRow(pos):向rows集合中的指定位置插入一行。

为元素添加的属性和方法:

rows:保存着元素中行的HTMLCollection。
deleteRow(pos):
insertRow(pos):

为tr元素添加的属性和方法:

cells:保存着元素中单元格的HTMLCollection.
deleteCell(pos):删除指定位置的单元格
insertCell(pos):向Cells集合中的指定位置插入一个单元格。

使用NodeList

NodeList,NamedNodeMap,HTMLCollection:这三个集合都是动态的。每当文档结构发生变化时,他们都会得到更新。
一般来说,应该尽量减少访问NodeList的次数,因为每次访问NodeList都会运行一次基于文档的查询。所以可以考虑将从NodeList中取得的值缓存起来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值