js 高程学习总结 第十章 DOM

DOM 文档对象模型
节点层次
每个文档的根节点:文档节点;对于html页面来说文档节点只有一个子节点:元素,称之为文档元素
总共有12种节点类型
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);

由于IE没有公开Node类型的构造函数

if(someNode.nodeType == Node.ELEMENT_NODE){
    console.log("node is");
}//IE中无效
if(someNode.nodeType == 1){//使用所有浏览器
}

节点关系
每个节点都有一个childNodes属性,其中包含着一个NodeList对象;NodeList对象是基于DOM结构动态执行查询的结构,不是一成不变的,可以用方括号来访问NodeList的值,而且有length属性,但是它并不是Array实例;
NodeList可以通过方括号也可以使用item()方法来访问;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列表中的所有节点都具有相同的父节点,每个节点相互之间都是同胞节点;
previousSibling和nextSibling 属性,第一个节点的previousSibling是null,最后一个节点 的nextSibling是null;
hasChildNodes() 若节点包含一或多个子节点返回true,所有节点最后一个属性是ownerDocument,该属性指向整个文档的文档节点
操作节点
appendChild():在childNodes列表的末尾添加一个节点,如果将父节点的第一个子节点传入时,那么该节点就会成为父节点的最后一个子节点
insertBefore():接受两个参数:要插入的节点,作为参照的节点;被插入的节点会被返回
replaceChild():接受两个参数,要插入的节点,要替换的节点;要替换的节点将会返回并从文档树中移除
removeChild():参数,要移除的节点;被移除的节点将成为方法的返回值
cloneNode():参数true(执行深复制),false(执行浅复制)

Document类型
Document 表示整个HTML页面,是window对象的一个属性;
其中nodeType 为9;nodeName为“#document”;
nodeValue为null;parentNode为null;ownerDocument 为null;
document.documentElement//对html的引用
document.body//取得对body的引用
document.doctype//取得对的引用;但是不同浏览器对其支持不同, 因此作用很有限
文档信息
document.title//文档标题,可以获取和设置
document.URL//包含页面完整的URL,地址栏中的URL
document.domain//只包含页面的域名
document.referrer// 链接到当前页面的那个页面url
其中只有domain 是可以设置的;但是有安全方面的限制,如URL中包含一个子域名,例如p2p.wrox.com,那么只能将domain 设置为“wrox.com”
如果页面中有包含来自其他子域的框架或者内嵌框架时,能够设置document.domain来相互访问对方的js对象
domain属性还有一个限制:如果域名开始是松散的,就不能在将它设置为紧绷的,即将document.domain 设置为“wrox.com”之后,就不能再将其设置回“www.wrox.com”
查找元素
document.getElementById() 和getElementsByTagName();
getElementById : 接收要取得元素的ID(是区分大小写的),如果找到则返回该元素,如果不存在,则返回null,如果多个元素的id相同,只返回文档中第一次出现的元素//并且不要让表单字段的name与其他元素的ID相同
getElementsByTagName:要取得元素的标签名,返回包含0或多个元素的NodeList;在html文档中,该方法会返回一个HTMLCollection 对象,作为一个“动态”集合,HTMLCollection 对象有一个namedItem方法,可以通过元素的name特性返回集合中的项;还有item方法,按照索引查找项;
还可以对命名的项使用方括号语法来访问

var images = document.getElementsByTagName("img");
var myImage = images["myImage"];//可以传入数值或字符串,数值索引后台就调用item(),字符串就调用namedItem();

getElementsByName();//最常使用的情况是取得单选按钮

var radios = document.getElementsByName("color")//会返回一个HTMLCollection,但是对于单选按钮来说,namedItem()只会取得第一项;

特殊集合
document.anchors// 所有带name特性的a标签
document.applets//所有applet集合,但是已经不再推荐使用applet元素
document.forms//所有form元素
document.images //所有img元素
document.links //所有带有href的a元素

* DOM一致性 *
由于DOM分为多个级别,也包含多个部分,因此检测浏览器实现了DOM哪些部分就十分必要了,DOM1级只为document.implementation规定了一个方法,即hasFeature(),此方法接收两个参数,要检测的DOM功能的名称及版本号
文档写入
将输入流写入网页中的能力:write、writeln(会换行)、open、close。
其中前两个方法接受一个字符串参数,即要写入到输出流中的文本;可以是向页面中动态地加入内容, 也可以动态的包含外部资源,如:

document.write("<script type=\"text/javascript\"src = \"file.js\">"+"</script>")//这样将会无法执行,因为字符串“</script>”将会被解释为与外部的<script>标签匹配,则")将会出现在页面上;

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

open和close 为打开和关闭网页的输出流,如果在页面中调用write、writeln方法,则不需要使用这两个方法

Element类型
nodeType值为1、nodeName值为元素的标签名,nodeValue值为null,parentNode 可能为Document或Element;子节点可能为Element、Text、Comment、ProcessingInstruction、CDATSection或EntityReference

div.tagName // “DIV”,而非“div”
因此element.tagName.toLowerCase() == “div” //这样最好

HTML 元素:id元素在文档中的唯一标识符;title 元素的附加说明信息;lang 语言代码,很少使用;dir 语言的方向,ltr 或者rtl ,也很少使用;className 与元素的class特性赌赢,指定元素的css类,没将其命名为class,因为class是ECMAScript的保留字

取得特性:getAttribute(),setAttribute(),removeAttribute();
getAttribute:其中获取class特性值,应该传入class而不是className,后者只有在通过对象属性访问特性时才用,如果给定名称的特性不存在,该方法会返回null;
有两类特殊的特性:他们虽然有对应的属性名,但属性的值与通过getAttribute返回的值并不相同,第一类是style,通过getAttribute访问时,会返回style特性值中包含的css文本,而通过属性访问返回的是一个对象;第二类特性是onclick这样的事件处理程序,如果通过getAttribute 则会返回相应代码的字符串,访问onclick属性时会返回一个javascript函数(如果未在元素中指定相应特性,则返回null);一般只有访问自定义特性值时,才会访问getAttribute方法,其他时候使用对象的属性

设置特性
setAttribute():接受两个参数,要设置的特性名和值,如果特性已经存在,会替换现有的值,如果不存在,会创建该属性并设置相应的值

div.mycolor = "red";
div.getAttribute("mycolor");//null IE除外

attributes属性
Element类型时使用attributes属性的唯一DOM节点类型,其中包含一个NamedNodeMap,与NodeList类似,是一个动态集合;NamedNodeMap 对象拥有下列方法
getNamedItem(name) //返回nodeName属性等于name的节点
removeNamedItem(name) //删除nodeName属性等于name的节点
setNamedItem(node) //向列表中添加节点,以节点的nodeName属性为索引
item(pos) //返回位于数字pos位置处的节点
attributes中包含一系列节点,每个节点的nodeName就是特性的名称,而节点的nodeValue就是特性的值
创建元素
document.createElement() 方法可以创建新元素
document.body.appendChild();//将元素添加到文档树

元素的子节点
childNodes属性包含了节点的所有子节点
ul.getElementsByTagName(“li”);//查找ul的li后代

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为止处的字符串
可以通过nodeValue 来访问

div.firstChild.nodeValue = "some other message";

创建文本节点
var textNode = document.createTextNode(“Hello World”);
element.appendChild(textNode);
规范化文本节点:
如果父元素上含有两个或多个文本节点,可以在父元素上调用normalize()方法,会将所有文本节点合并成一个节点;
分割文本节点
splitText():会将一个文本节点分成两个文本节点,原来的文本节点将包含从开始到指定位置之前的内容,新文本节点包含剩下的文本,这个方法会返回一个新文本节点;

comment类型
nodeType 是8;nodeName是 “#comment”;nodeValue的值是注释的内容;parentNode可能是Document或Element,不支持子节点;
该类型与Text类型继承自相同的基类,拥有除了splitText之外的所有字符串操作方法。也可以通过nodeValue或data属性来取得注释内容;
其中document.createComment()可以创建注释节点,但是开发人员很少创建和访问注释节点,因为注释节点对算法鲜有影响,浏览器也不会识别位于之后的注释;

CDATASection 类型
只针对基于XML的文档,表示CDATA区域;
DocumentType类型
仅有Firefox Safari 和Opera支持它。它包含着与文档的doctype有关的所有信息
DocumentFragment 类型
不能将文档片段直接添加到文档中,但是会将它作为一个“仓库”使用,即可以在里面保存将来可能会添加到文档中的节点。如向ul中添加多个li;

var fragment = document.createDocumentFragment();
var ul = document.getElementById("myList");
var li = null;
for (var i = 0; i < 3; i++){
    li = document.createElement('li');
    li.appendChild(document.createTextNode("Item"+(i+1)));
    fragment.appendChild(li);
}
ul.appendChild(fragment);

Attr类型
元素的特性
有3个属性:name(特性名称)、value(特性的值,与nodeValue相同)和specified(布尔值,用于区别特性在代码中是指定的还是默认的);
var attr = document.createAttribute(“align”)//创建新的特性节点,为元素添加了align特性
attr.value = “left”;
element.setAttributeNode(attr);//为了将新创建的节点特性添加到元素中,必须使用元素的这个方法;
下面是怎么访问该特性:
element.attributes[“align”].value;//”left”
element.getAttributeNode(“align”).value;//”left”
element.getAttribute(“align”);//”left”;

DOM 操作技术

创建动态脚本的两种方式

  • 插入外部文件<script type="text/javascript" src="client.js"></script>
  • 直接插入javascript代码;<script type="text/javascript" >function sayHi(){console.log("hi")}</script>
function loadScript(url){
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = url;
    document.doby.appendChild(script);
}

动态样式
能够把css样式包含到HTML页面中的元素有两个,其中 link元素用于包含来自外部的文件,而style元素用于指定嵌入的样式

<link rel="stylesheet" type="text/css" href="styles.css">
//使用DOM代码可以很容易地动态创建出这个元素
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);//必须放在head中才行
}


<style type="text/css">
    body {
        background-color: red;
    }
</style>

操作表格
使用NodeList
NodeList、NamedNodeMap、HTMLCollection,从整体上透彻理解DOM的关键所在,每当文档发生变化时,他们都会得到更新

var divs = document.getElementsByTagName("div"),
    i,div;
for(i=0;i<divs.length;i++){
    div = document.createElement("div");
    document.body.appendChild(div)
}
//上述方法会陷入死循环,因为每次求值divs.length 都会运行取得所有div元素的查询

//应该在for循环初始化时求出length
for(i = 0,len = divs.length;i<len;i++){
}

一般来说,应该减少访问NodeList的次数,因为每次访问NodeList,都会运行一次机遇文档的查询,所以可以考虑将从NodeList中取得的值缓存起来;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值