- 节点之间的关系构成了层次,而所有页面标记则表现为一个以特定节点为根节点的属性结构;
- 文档节点是每个文档的根节点,文档节点的子节点是html元素;文档元素是文档的最外层元素,文档中的其他所有元素都包含在文档元素中;
- node类型;开发人员最常用的就是 元素和文本节点;
nodeType nodeName nodeValue
元素类型 1 标签名 null
文本类型 3 #text 包含的的文本
属性类型 2 属性的名称 属性的值
注释类型 8 #comment 注释的内容
document类型 9 #document null
一、Node类型:
- 每个节点都有一个childNodes属性,其中保存着NodeList对象,这个对象也有length属性;访问NodeList可以用[]还可以用item()方法;
var btn = document.getElementById("box");
// console.log(btn.childNodes[2]);
// console.log(btn.childNodes.item(2));
console.log(btn.childNodes.length);
//将childNodes中的nodeList转换为数组;
var btn = document.getElementById("box");
var arrNode = btn.childNodes;
console.log(arrNode);
var arr = [];
for(var i = 0;i<arrNode.length;i++){
arr.push(arrNode[i]);
}
console.log(arr);
- parentNode:每个节点都有一个parentNode属性,该属性指向文档树中的父节点;包含在childNodes列表中的所有节点都具有相同的父节点,因此他们的parentNode属性指向同一个节点;
- previousSibling :上一个同胞节点;
- nextSibling:下一个同胞节点;
- 其中列表中只有一个节点:previousSibling和nextSibling都为null;
- firstChild:指childNodes列表中的第一个节点; someNodes.childNodes[0] = someNodes.firstChild;
- lastChild:指childNodes列表中的最后一个节点;
someNodes.childNodes[someNodes.childNodes .length-1] = someNodes.firstChild;
- 在只有一个子节点的情况下,firstChild等于lastChild;
操作节点:
- appendChild:向childNodes末尾添加节点,appendChild返回新增的节点;
<body>
<ul id="box">
<li>dfsafdsaf1</li>
<li>dfsafdsaf2</li>
<li>dfsafdsaf3</li>
<li>dfsafdsaf4</li>
</ul>
</body>
<script>
var btn = document.getElementById("box");
var Li = document.createElement("li");
var res = btn.appendChild(Li);
console.log(res); //返回新添加的li节点
</script>
- insertBefore() :将节点添加到childNodes中指定的位置上,而不是放在末尾;有两个参数:要插入的节点和作为参照的节点;插入节点后,被插入的节点会会变成参照节点的前一个同胞节点;如果参照的节点是null则insertBefore与appendChild执行相同的操作;
<body>
<ul id="box">
<li>dfsafdsaf1</li>
<li>dfsafdsaf2</li>
<li>dfsafdsaf3</li>
<li>dfsafdsaf4</li>
</ul>
</body>
<script>
var btn = document.getElementById("box");
var Li = document.createElement("li");
var text = document.createTextNode("我是插入的节点");
Li.appendChild(text);
//插入后成为最有一个子节点;
// var returnNode = btn.insertBefore(Li,null)
// 插入后成为第一个子节点;
// var returnNode = btn.insertBefore(Li,btn.firstChild);
// 插入到最后一个子节点前面;
// var returnNode = btn.insertBefore(Li,btn.childNodes[btn.childNodes.length-2]);
</script>
- replaceChild();替换节点,包含两个参数:要插入的节点和要替换的节点;移除的节点仍然为文档所有,只是在文档中没有了自己的位置;
<body>
<ul id="box">
<li>dfsafdsaf1</li>
<li>dfsafdsaf2</li>
<li>dfsafdsaf3</li>
<li>dfsafdsaf4</li>
</ul>
</body>
<script>
var btn = document.getElementById("box");
var Li = document.createElement("li");
var text = document.createTextNode("我是插入的节点");
Li.appendChild(text);
//替换第一子节点;
// var returnNode = btn.replaceChild(Li,btn.firstChild)
//替换最后一个子节点;
var returnNode = btn.replaceChild(Li,btn.lastChild) ;
</script>
- removeChild():删除文档中的节点;只接受一个参数:即要移除的节点;仍然为文档所用,只是在文档中没有自己的位置了;
<body>
<ul id="box">
<li>dfsafdsaf1</li>
<li>dfsafdsaf2</li>
<li>dfsafdsaf3</li>
<li>dfsafdsaf4</li>
</ul>
</body>
<script>
var btn = document.getElementById("box");
var Li = document.createElement("li");
var text = document.createTextNode("我是插入的节点");
Li.appendChild(text);
//移除子一个子节点
// var returnNode = btn.removeChild(btn.firstChild)
//移除最后一个子节点;
// var returnNode = btn.removeChild(btn.lastElementChild)
</script>
- cloneNode() :创建节点的完全相同的副本; 接收一个参数 参数为true,是深复制,复制节点及其整个子节点树;参数为false,执行浅复制,只复制节点本身;复制后返回文档节点及其整个子节点树;只能通过appendChild、insertBefore、replaceChild添加到文档中;
<body>
<ul id="box">
<li>dfsafdsaf1</li>
<li>dfsafdsaf2</li>
<li>dfsafdsaf3</li>
<li>dfsafdsaf4</li>
</ul>
</body>
<script>
var btn = document.getElementById("box");
// 深复制
var deepList = btn.cloneNode(true);
btn.insertBefore(deepList,btn.lastChild)
console.log(deepList); //复制了ul元素和他的子元素;
//浅复制;
var shadowList = btn.cloneNode(false);
btn.insertBefore(shadowList,btn.firstChild);
console.log(shadowList);//只复制了ul元素;
</script>
二、Document类型
文档的子节点:
- 访问document的子节点有两种方法:document.documentElement document.childNodes[1]
第一个节点为 <!DOCTYPE html> 访问的时候用document.doctype
- 还有一个经常使用的访问body元素的:document.body
- 因为只读,所以只能访问不能修改;所以不能在document上调用appendChild() insertBefore() replaceChild()方法;
文档信息:
- document.title 可以取得当前页面的标题,也可以写该当前页面的标题并反映在浏览器的标题栏中;
- URL domain referrer docuemnty.URL:包含页面中完整的URL,即地址栏中显示的;
document.domain :包含页面中的域名;
document.referrer :链接到当前页面的那个页面的URL;如下:jjj.html中有a链接到lizi.html所以在lizi页面获取document.referrer时,就会获取到jjj页面;
例:
console.log(document.URL); //http://localhost:63342/%E7%BB%83%E4%B9%A0/lizi.html
console.log(document.domain); //localhost
console.log(document.referrer); //http://localhost:63342/%E7%BB%83%E4%B9%A0/jjj.html?_ijt=7qgnr07h8m7aih9djkot1if4jf
查找元素
- documnet.getElementById(); 通过id获取元素,如果多个元素的ID相同,只返回文档中第一次出现的元素;
- document.getElementsByTagName(); 通过标签名获取元素;返回的是0或多个元素的NodeList
可以访问该获取的元素:1.用方括号访问 2.用item()访问;还有一个方法用namedItem():通过name获取集合中的项;
var imgs = document.getElementsByTagName("img");
console.log(imgs[0]);
console.log(imgs.item(0));
console.log(imgs.namedItem("mynam"));
要获取文档中的所有元素可以用:document.getElementsByTagName("*");
- 通过document.getElementsByName() 获取元素;
特殊集合
- document.forms包含文档中所有的form元素;
- document.images包含文档中所有的img元素;
- document.links 好汉文档中所有的带href的a链接;
文档写入
- document.write()、document.writeIn() 接收一个字符串参数,即要写入到输出流中的文本;
- document.open() document.close() 打开和关闭网页的输出流;
三、Element类型
- 访问元素的标签名:tagName
var imgs = document.getElementsByTagName("img")[0];
console.log(imgs.tagName);//IMG以大写的形式返回;
console.log(imgs.tagName.toLowerCase() == "img"); //true
- html元素:元素中存在着一下标准特性:id、title、className、dir、lang;可以通过js取得,也可以通过js重新设值;
var oP = document.getElementById("tex");
获取特性:
console.log(oP.id);
console.log(oP.className);
console.log(oP.title);
设置特性:
var oP = document.getElementById("tex");
oP.title = "我是新标题";
oP.classNama = "new";
oP.id = "newText"
- 取得特性:getAttribute() setAttribute() removeAttribute()
getAttribute():获取属性,也可以获取自定义属性;开发人员一般不使用getAttribute() 而是只使用对象属性,一般取得自定义的特性值的情况下才会使用getAttribute();
- 设置特性
setAttribute() 设置特性,包含两个参数:要设置的特姓名和值;如果特性已经存在,setAttribute会以指定的值替换现有的值,如果不存在就创建该属性;
- 删除属性:
removeAttribute() 删除属性;
- attributes 可以用来遍历元素的属性;
var oP = document.getElementById("tex");
console.log(oP.attributes);//{0: id, 1: class, 2: title, length: 3}
- 创建元素:document.createElement("")只接受一个参数,既要创建元素的标签名;要将创建的元素添加到文档中可以使用appendChild() insertBefore() replaceChild()
四、Text类型
- 可以通过nodeValue访问文本; 文本节点属于元素的子节点;
<body>
<p id="box">fdsafsafsaf</p>
</body>
<script>
var btn = document.getElementById("box");
console.log(btn.firstChild.nodeValue);
</script>
- 创建文本节点; document.createTextNode();
创建一个div元素,并在div元素中添加节点;
var oDiv = document.createElement("div");
var Text = document.createTextNode("hello world");
oDiv.appendChild(Text);
document.body.appendChild(oDiv);
- 规范化文本节点; normalize()在含有一个或者多个文本节点的父元素上调用这个方法,则会将所有文本节点合并为一个节点;
var oDiv = document.createElement("div");
var Text = document.createTextNode("hello world");
var anotherText = document.createTextNode("这是第二个文本节点");
oDiv.appendChild(Text);
oDiv.appendChild(anotherText);
document.body.appendChild(oDiv);
console.log(oDiv.childNodes.length); //2 两个子元素;
oDiv.normalize();
console.log(oDiv.childNodes.length); //1 将两个文本节点合并
- 分割文本节点;splitText()将一个文本节点分割成两个文本节点;原来的文本节点将包含从开始到指定位置之前的内容,新闻本节点将包含剩下的节点; 这个方法会返回一个新的文本节点;
var oDiv = document.createElement("div");
var Text = document.createTextNode("hello world");
oDiv.appendChild(Text);
document.body.appendChild(oDiv);
var newText = oDiv.firstChild.splitText(5);
console.log(oDiv.firstChild.nodeValue); //hello
console.log(newText); //world
分割文本节点是从文本节点中提取数据的一种常用DOM解析技术;
五、Comment类型
- 注释节点与Text文本节点类型继承自相同的基类,因此特拥有除splitText()之外的所有字符创操作方法。
- 注释节点可以通过其父节点访问;
- 创建注释节点document.createComment();
- 但是注释节点很少用到,因为注释节点对算法有影响;
六、Attr类型
- 开发人员最长使用的方法是:getAttribute() setAttribute() removeAttribute()
- 有3个属性:name value specified name特性名称 value特性值 specified 用于区分特性是在代码中指定的还是默认的;
- 创建属性节点:document.createAttribure();
- 为创建新的特性添加到元素中,必须使用元素setAttributeNode()
- 创建以后访问的时候可以使用attributes getAttributeNode() 和 getAttribute() 前两个返回特性的attr节点,后一个返回的是节点的值;
var oDiv = document.getElementById("box");
var attr = document.createAttribute("title");
attr.value = "这是动态添加的title";
oDiv.setAttributeNode(attr) //
console.log(oDiv.attributes["title"]);//title = "这是动态添加的title"
console.log(oDiv.getAttributeNode("title"))//title = "这是动态添加的title"
console.log(oDiv.getAttribute("title")) //这是动态添加的title
DOM操作技术;
- 动态脚本;创建动态脚本有两种方法: 插入外部文件 直接插入js代码;
//将创建script封装在一个函数里面,什么时候需要添加什么时候就调用这个函数;
function loadScript(){
//在body或者head中插入脚本;
var script = document.createElement("script");
script.src = "jquery.min.js";
// document.head.appendChild(script);
document.body.appendChild(script);
}
loadScript()
- 动态样式 :是页面加载完成后动态添加到页面中去的;
以link为例:
function loadLink(){
var oLink = document.createElement("link");
oLink.rel = "stylesheet";
oLink.href = "css.css";
var head = document.getElementsByTagName("head")[0];
head.appendChild(oLink);
}
loadLink();
注:link必须添加到head中;
操作表格
- 为table元素添加属性和方法:
rows :保存table元素中的行;
deleteRow(pos):删除指定位置的行;
insertRow(pos):向row集合中指定位置插入一行,返回对新插入行的引用;
cells:保存着tr元素中的单元格;
deleteCells(pos):删除指定位置的单元格;
insertCell(pos) : 向集合中的指定位置插入单元格;返回对新单元格的引用;
window.onload = function(){
var table = document.createElement("table");
table.insertRow(0);
var text1 = document.createTextNode("我是第一行第一个单元格");
var text2 = document.createTextNode("我是第一行第二个单元格");
table.rows[0].insertCell(0).appendChild(text1);
table.rows[0].insertCell(1).appendChild(text2);
// 添加第二行
table.insertRow(1);
var text3 = document.createTextNode("我是第二行第一个单元格")
var text4 = document.createTextNode("我是第二行第二个单元格")
table.rows[1].insertCell(0).appendChild(text3);
table.rows[1].insertCell(1).appendChild(text4);
document.body.appendChild(table)
}
table.rows[i] 获得table的第几行;
table.rows[i].cells[i]获得第几行的第一个单元格;