HTML可以描绘成一个多层节点构成的结构,文档节点是每个文档的根节点,元素被称之为文档元素,是文档的最外层元素。不同的标记用不同的节点来表示。
1. Node类型
Node接口在Javascript中是作为Node类型实现的,除了IE之外,在其他所有浏览器中都可以访问到这个类型。而Javascript的所有节点类型都继承自Node类型。
-
1.1nodeType属性
表明节点类型:1.Node.ELEMENT_NODE,2.Node.ATTRIBUTE_NODE,3.Node.TEXT_NODE,4.Node.CDATA_SECTION_NODE,5.Node.ENTITY_REFERENCE_NODE,6.Node.ENTITY_NODE,7.Node.PROCESSING_INSTRUCTION_NODE,8.Node.COMMENT_NODE,9.Node.DOCUMENT_NODE,10.Node.DOCUMENT_TYPE_NODE,11.Node.DOCUMENT_FRAGMENT_NODE,12.Node.NOTATION_NODE
var btn1 = document.getElementsByClassName('btn1')[0];
if(btn1.nodeType == 1){
console.log('这是元素节点');
}
-
1.2nodeName 和 nodeValue 属性
//对于元素节点,nodeName中保存的始终都是元素的标签名,而nodeValue的值则始终为null
console.log(btn1.nodeName);//这里是一个按钮,所以打印BUTTON
console.log(btn1.nodeValue);
-
1.3节点关系
- childNodes:NodeList 对象,NodeList 对象是类数组对象,用于保存一组有序的节点。
html:
- 第一行
- 第二行
- 第三行
js:
var ulList = document.getElementsByClassName('ul-list')[0];
console.log(ulList.childNodes);
var first = ulList.childNodes[0];
console.log(first);
var last = ulList.childNodes[ulList.childNodes.length-1];
console.log(last);
//hasChildNodes()方法判断是否有子节点
console.log(ulList.hasChildNodes());
//ownerDocument返回所在的文档,而且每个节点只能在一个文档中
console.log(ulList.ownerDocument);
- parentNode:父节点
//打印ulList
console.log(last.parentNode);
- previousSibling和nextSibling
console.log(second.previousSibling);//打印第三行
console.log(second.nextSibling);//打印第一行
console.log(last.nextSibling);//打印null
- firstChild和lastChild
console.log(ulList.firstChild);//打印第一行
console.log(ulList.lastChild);//打印第三行
-
1.4操作节点
- appendChild()
html:
div中的第一行
div中的第二行
div中的第三行
js:
var div1 = document.getElementsByClassName('div-con')[0];
var p = document.createElement("p");
p.innerText = '这是新创建的段落';
//返回值是被添加的子节点
var appendP = div1.appendChild(p);
console.log(appendP == p);
//如果传入到 appendChild()中的节点已经是文档的一部分,那么就是将该节点从原来的位置转移到新位置
var secondP = document.getElementsByClassName('second-p')[0];
div1.appendChild(secondP);
- insertBefore()
var div1 = document.getElementsByClassName('div-con')[0];
var secondP = document.getElementsByClassName('second-p')[0];
var p = document.createElement("p");
p.innerText = '这是新创建的段落';
//insertBefore:指定放到某个子节点之前,如果第二个参数传null,则新节点会被放在最后
div1.insertBefore(p,secondP);
- replaceChild()
var div1 = document.getElementsByClassName('div-con')[0];
var secondP = document.getElementsByClassName('second-p')[0];
var p = document.createElement("p");
p.innerText = '这是新创建的段落';
//replaceChild:替换子节点
div1.replaceChild(p,secondP);
- removeChild()
var div1 = document.getElementsByClassName('div-con')[0];
var secondP = document.getElementsByClassName('second-p')[0];
//removeChild:删除子节点
div1.removeChild(secondP);
-
1.5其他方法
- cloneNode()
var ulList = document.getElementsByClassName('ul-list')[0];
var div1 = document.getElementsByClassName('div-con')[0];
//cloneNode:传是否深复制的参数,true为深复制(把子节点也复制过来),false则否.
//事件处理程序不会被复制,但IE有bug,会复制事件处理程序,所以复制之前最好把事情处理程序去掉
var cloneList = ulList.cloneNode(true);
console.log(cloneList);
//注意的是,cloneNode完之后必须要为它指定父节点,不然它无法显示
div1.appendChild(cloneList);
- normalize
这个方法唯一的作用就是处理文档树中的文本节点。 由于解析器的实现或 DOM 操作等原因,可能会出现文本节点不包含文本,或者接连出现两个文本节点 的情况。当在某个节点上调用这个方法时,就会在该节点的后代节点中查找上述两种情况。如果找到了 空文本节点,则删除它;如果找到相邻的文本节点,则将它们合并为一个文本节点。
2.Document类型
在浏览器中,document对象是window的属性,可以直接访问.而document对象是HTMLDocument类型的实例(HTMLDocument类型继承自Document类型),document对象表示整个文档。
-
2.1文档的子节点
console.log(document);
//为9
console.log(document.nodeType);
//为:#document
console.log(document.nodeName);
//为null
console.log(document.nodeValue);
//为null
console.log(document.parentNode);
//为null
console.log(document.ownerDocument);
//打印子节点:子节点可能有DocumentType,Element,ProcessingIn-struction,Comment.
//兼容性的问题是不同浏览器对于出现在以外的注释Comment是否加入到document的子节点中不一致
console.log(document.childNodes);
var docuChild = document.childNodes;
for(var i=0,len=docuChild.length;i元素
console.log(document.documentElement);
//指向元素
console.log(document.body);
-
2.2文档信息
//有一些属性是Document类型没有,是HTMLDocument类型才有的属性:
//标题
console.log(document.title);
//可以修改文档标题
document.title = 'bom学习';
//URL:完整URL地址,domain:域名,referrer:来源页面的URL(如果没有就是空字符串)
console.log(document.URL);
console.log(document.domain);
console.log(document.referrer);
//可以设置domain:当页面中包含来自其他子域的框架或内嵌框架时,能够设置document.domain就非常方便了。
//由于跨域安全限制,来自不同子域的页面无法通过 JavaScript 通信。
//而通过将每个页面的 document.domain 设置为相同的值,
//这些页面就可以互相访问对方包含的 JavaScript 对象了
//不能将这个属性设置为URL中不包含的域
//假设页面来自 p2p.wrox.com 域
document.domain = "wrox.com"; // 成功
document.domain = "nczonline.net"; // 出错!
//浏览器对domain属性还有一个限制,即如果域名一开始是“松散的”(loose),那么不能将它再设置为“紧绷的”(tight)
//假设页面来自于 p2p.wrox.com 域
document.domain = "wrox.com"; //松散的(成功)
document.domain = "p2p.wrox.com"; //紧绷的(出错!)
-
2.3查找元素
- getElementById():返回文档中指定id特性的元素,只返回文档中第一次出现指定id的元素。兼容性:①IE8 及较低版本不区分 ID 的大小写,其他浏览器都会区分;②IE7及更低版本:name 特性与给定 ID 匹配的表单元素(、
- getElementsByTagName():返回的是包含零或多个元素的 NodeList,在 HTML 文档中,这个方法会返回一个 HTMLCollection 对象。
//将HTMLCollection对象保存在lis变量中
var imgs = document.getElementsByTagName('img');
console.log(imgs);
//获取其中某个元素:①item()方法
console.log(imgs.item(0));
//②类似数组传个index:底层调用了item()方法
console.log(imgs[0]);
//③使用这个方法可以通过元素的name特性取得集合中的项
console.log(imgs.namedItem('shop'));
//④HTMLCollection 还支持按名称访问项:底层调用了namedItem()方法
console.log(imgs["changephone"]);
//如果传入*当做tagName的话,会返回所有的元素
var allEles = document.getElementsByTagName("*");
- getElementsByName():HTMLDocument类型才有的方法.
这个方法会返回带有给定 name 特性的所有元素,也是HTMLCollectioin集合.
html:
js:
var radios = document.getElementsByName('fruit');
console.log(radios);
-
2.4特殊集合
除了属性和方法,document 对象还有一些特殊的集合。这些集合都是 HTMLCollection 对象, 为访问文档常用的部分提供了快捷方式:
html:
百度
漂书
淘宝
js:
//包含文档中所有的
-
2.5DOM一致性检测
DOM分为多个级别,也包含多个部分,所以一致性检测有需要:
//参数:要检测的 DOM 功能的名称及版本号,如果实现了就返回true
console.log(document.implementation.hasFeature('HTML','2.0'));
但hasFeature的返回有时会不准确(浏览器可能是返回了true但并未全部实现),所以大多数情况下推荐使用 能力检测.
-
2.6文档写入
//文档写入:writeln和write的区别是writeln在写入之后加了一个'\n'符
//还可以写入script文件等等,注意对"和/script的转义
document.write("" + (new Date()).toLocaleString() + "");
document.writeln("
");
document.write("