DOMcss
學習要點:
1.DOM介紹
2.查找元素
3.DOM節點
4.節點操做html
DOM(Document Object Model)即文檔對象模型,針對HTML和XML文檔的API(應用程序接口)。DOM
描繪了一個層次化的節點樹,運行開發人員添加、移除和修改頁面的某一部分。DOM脫胎於Netscape及微軟
公司創始的DHTML(動態HTML),但如今它已經成爲表現和操做頁面標記的真正跨平臺、語言中立的方式。node
1、DOM介紹
DOM中的三個字母,D(文檔)能夠理解爲整個Web加載的網頁文檔:O(對象)能夠理解爲相似window對象
之類的東西,能夠調用屬性和方法,這裏咱們說的是document對象;M(模型)能夠理解爲網頁文檔的樹形結構。數組
DOM有三個等級,分別是DOM一、DOM二、DOM3,而且DOM1在1998年10月成爲W3C標準。DOM1所支
持的瀏覽器包括IE6+、Firefox、Safari、Chrome和Opera1.7+。瀏覽器
PS:IE中的全部DOM對象都是以COM對象的形式實現的,這意味着IE中的DOM可能會和其餘瀏覽器有必定的
差別。app
1.節點
加載HTML頁面時,Web瀏覽器生成一個樹型結構,用來表示頁面內部結構。DOM將這種樹型結構理解爲由節點
組成。
節點樹
html
|-----------------------------------|
head body
|------------------| |----------|----------|
meta title h1 p ul
|---------|---------|
li li li
從上面的樹型結構,咱們理解幾個概念,htm標籤沒有父輩,沒有兄弟,因此html標籤爲根標籤,head標籤是
html子標籤,meta和title標籤之間是兄弟關係。若是把每一個標籤看成一個節點的話,那麼這些節點組合成了一
棵節點樹。函數
PS:後面咱們常常把標籤稱爲元素,是一個意思。學習
2.節點種類;元素節點、文本節點、屬性節點。測試
<div title = '屬性節點'>測試Div</div>
元素節點
div
|------------------------|
title='標籤屬性' 測試Div
屬性節點 文本節點
PS:節點分爲三類
1.元素節點:其實就是標籤,<div></div>
2.文本節點:其實就是標籤內的純文本,測試Div
3.屬性節點:其實就是標籤的屬性,id='box'指針
2、查找元素
W3C提供了比較方便簡單的定位節點的方法和屬性,以便咱們快速的對節點進行操做,分別爲:getElementById()、
getElementsByTagName()、getElementsByName()、getAttribute()、setAttribute()和removeAttribute()。
元素節點方法
方法 說明
getElementById() 獲取特定ID元素的節點
getElementsTagName() 獲取相同元素的節點列表
getElementsByName() 獲取相同名稱的節點列表
getAttribute() 獲取特定元素節點屬性的值
setAttribute() 設置特定元素節點屬性的值
removeAttribure() 移除特定元素節點屬性
1.getElementById()方法
getElementById()方法,接受一個參數:獲取元素的ID。若是找到相應的元素則返回該元素的HTMLDivElement對象,
若是不存在,則返回null。
document.getElementById('box'); //獲取id爲box的元素節點
PS:上面的例子,默認狀況返回null,這無關是否存在id="box"的標籤,而是執行順序問題,解決方法:
1.把script調用標籤移到html末尾便可
2.使用onload事件來處理JS,等待html加載完畢再加載onload事件裏的JS。
window.onload = function(){ //預加載html後執行
var box = document.getElementById("box");
alert(box);
}
PS:id表示一個元素節點的唯一性,不能同時給兩個或者兩個以上的元素節點建立同一個命名的id。某些版本的
瀏覽器會以沒法識別getElementById()方法,好比IE5.0,這時須要作一些判斷,能夠結合上章的瀏覽器檢測來操
做。
if(document.getElementById){ //判斷是否支持getElementById
alert("當前瀏覽器支持getElementById");
}
具體判斷代碼:
window.onload=function(){
if(document.getElementById){ //判斷是否支持getElementById
var box = document.getElementById("box");
alert(box);
}else{
alert("當前瀏覽器不支持getElementById");
}
}
當咱們經過getElementById()獲取到特定元素節點時,這個節點對象就被咱們獲取到了,而經過這個節點對象,
咱們能夠訪問它的一系列屬性。
元素節點屬性
屬性 說明
tagName 獲取元素節點的標籤名
innerHTML 獲取元素節點裏的文本內容,非W3C DOM規範
document.getElementById('box').tagName; //DIV
document.getElementById('box').innerHTML; //測試Div
HTML屬性的屬性
屬性 說明
id 元素節點的id名稱
title 元素節點的title屬性值
style css內聯樣式屬性值
className css元素的類
document.getElementById('box').id; //獲取id,這個元素節點id屬性值,注意不是屬性節點
document.getElementById('box').id = 'person'; //設置id
document.getElementById('box').title; //獲取title,獲取title屬性的值
document.getElementById('box').title = '標題'; //設置title
document.getElementById('box').style; //獲取CSSStyleDeclaration屬性對象
document.getElementById('box').style.color; //獲取style屬性對象中color屬性的值
document.getElementById('box').style.color = 'red'; //設置style屬性對象中的color屬性的值
document.getElementById('box').className; //獲取class屬性的值
document.getElementById('box').className = 'box'; //設置class
以上是HTML屬性的直接調用,後面還有幾種方式的調用
alert(document.getElementById('box')bbb); //獲取自定義屬性的值,非IE不支持
2.getElementsByTagName()方法
getElementsByTagName()方法將返回一個對象數組HTML.Collection(NodeList),這個數組保存着全部相同元
素名的節點列表。
document.getElementsByTagName('*'); //獲取全部元素
//火狐瀏覽器的firebug打開以後會自動建立一個div因此在全部的元素上又加了一個元素的數量
//IE瀏覽器比火狐和谷歌多一個節點,是把<!文檔聲明也算進去了>
PS:IE瀏覽器在使用通配符的時候,會把文檔最開始的html的規範聲明看成一個元素節點。
document.getElementsByTagName('li'); //獲取全部li元素,返回數組
document.getElementsByTagName('li')[0]; //獲取第一個li元素,HTMLLIElement
document.getElementsByTagName('li').item(0); //獲取第一個li元素,HTMLLIElement
document.getElementsByTagName('li').length; //獲取全部li元素的數組
document.getElementsByTagName('body')[0]; //獲取body節點
PS:不論是getElementById仍是getElementsByTagName(),在傳遞參數的時候,並非全部瀏覽器都必須區
分大小寫,爲了防止沒必要要的報錯和麻煩,咱們必須堅持養成區分大小寫的習慣。
3.getElementsByName()方法
getElementsByName()方法能夠獲取相同名稱(name)的元素,返回一個對象數組HTMLCollection(NodeList).
document.getElementsByName('add'); //獲取input元素
document.getElementsByName('add')[0].value; //獲取input元素的value值
document.getElementsByName('add')[0].checked; //獲取input元素的checked值
PS:對於並非HTML合法的屬性,那麼在JS獲取的兼容性上也會存在差別,IE瀏覽器支持自己合法的name屬性
,而不合法的就會出現不兼容的問題。
4.getAttribute()方法
getAttribute()方法將獲取的元素中某個元素的屬性的值,它和直接使用屬性獲取屬性值的方法有必定的區別。
document.getElementById('box').getAttribute('id'); //獲取元素的id值
document.getElementById('box').id //獲取元素的id值
document.getElementById('box').getAttribute('mydiv'); //獲取元素的自定義屬性
document.getElementById('box').mydiv; //獲取元素的自定義屬性值,非IE不支持
document.getElementById('box').getAttribute('class'); //獲取元素的class值,非IE不支持
document.getElementById('box').getAttribute('className'); //非IE不支持
PS:HTML通用屬性style和onclick,IE7更低的版本style返回一個對象,onclick返回一個函數式。雖然IE8已經
修復了這個bug,可是爲了更好的兼容,開發人員只用儘量避免使用getAttribute訪問HTML屬性了,或者遇到
特殊的屬性獲取特殊的兼容處理。
//跨瀏覽器獲取className
if(document.getElementById('box').getAttribute('className') == null){
alert(document.getElementById('box').Attribute('class'));
}else{
alert(document.getElementById('box').Attribute('className'));
}
5.setAttribute()方法
setAttribute()方法將設置元素中某個元素屬性和值。它須要接受兩個參數:屬性名和屬性值。若是屬性自己已存在,
那麼就會被覆蓋。
document.getElementById('box').setAttribute('align' , 'center'); //設置屬性和值
document.getElementById('box').setAttribute('bbb' , 'ccc'); //設置自定義的屬性和值
PS:在IE7及更低版本中,使用setAttribute()方法設置class和style屬性是沒有效果的。雖然IE8解決了這個bug
,但仍是不建議使用。
6.removeAttribute()方法
removeAttribure()能夠移除HTML屬性。
document.getElementById('box').removeAttribure('style'); //移除style屬性
PS:IE6及更低版本不支持removeAttribute()方法。
3、DOM節點
1.node節點屬性
節點能夠分爲元素節點、屬性節點和文本節點,而這些節點又有三個很是有用的屬性。
分別爲:nodeName、nodeType和nodeValue。
信息節點屬性
節點類型 nodeName nodeType nodeValue
元素節點 元素名稱 1 null
屬性節點 屬性名稱 2 屬性值
文本節點 #text 3 文本內容(不包含html)
document.getElementById('box').nodeName; //獲取元素節點的標籤名,和tagName等效
document.getElementById('box').nodeType; //1,元素節點的類型值
document.getElementById('box').nodeValue; //元素節點自己沒有內容
//node自己把節點指針放在元素<div></div>上,也就是說,自己是沒有value
//若是要輸出<div>xxx</div>中裏面包含的文本內容,那麼前面innerHTML
alert(document.getElementById('box').innerHTML); //獲取元素節點裏面的文本內容
//node只能獲取當前節點的東西
PS:文本節點不等於文本內容
2.層次節點屬性
節點的層次結構能夠劃分爲:父節點與子節點、兄弟節點這兩種。當咱們獲取其中一個元素節點的時候,就能夠
使用層次節點屬性來獲取相關層次的節點。
層次節點屬性
屬性 說明
childNodes 獲取當前元素節點的全部子節點
fistChild 獲取當前元素節點的第一個子節點
lastChild 獲取當前元素節點的最後一個子節點
ownerDocument 獲取該節點的文檔根節點,至關於document
parentNode 獲取當前節點的父節點
previousSibing 獲取當前節點的前一個同級節點
nextSibing 獲取當前節點的後一個同級節點
attributes 獲取當前元素節點的全部屬性節點集合
1.childNodes屬性
childNodes屬性能夠獲取某一個元素節點的全部子節點,這些子節點包含元素子節點和文本子節點。
var box = document.getElementById('box'); //獲取一個元素節點
alert(box.childNodes.length); //獲取這個元素節點的全部子節點
alert(box.childNodes[0]); //獲取第一個子節點對象
window.onload=function(){
var box = document.getElementById('box');
//alert(box.childNodes); //NodeList集合,返回當前元素節點全部的子節點列表
//alert(box.childNodes.length); //3個子節點
//3個子節點爲:測試Div<em>傾斜</em>結尾
//第一個子節點爲:測試Div,這個節點稱爲:文本節點
//第二個子節點爲:<em>傾斜</em>:這個節點稱爲元素節點
//第三個子節點爲:結尾,這個是一個文本節點
//alert(box.childNodes[0]); //Object Text表示一個文本節點對象
//alert(box.childNodes[0].nodeName); //#text,文本節點沒有標籤名
//alert(box.childNodes[0].nodeType); //3,當前節點的屬性值爲文本節點
//alert(box.childNodes[0].nodeValue); //獲取文本節點的文本內容
//alert(box.childNodes[0].innerHTML); //undefined無效的
}
PS:使用childNodes[0]返回子節點對象的時候,有可能返回的是元素子節點。好比HTMLElement;也有可能
返回的是文本子節點,好比Text。元素子節點可使用nodeName或者tagName獲取標籤名稱,而文本子節點
可使用nodeValue獲取。
for(var i = 0 ; i<box.childNodes.length;i++){
//判斷是元素節點,輸出元素標籤名
if(box.childNodes[i],.nodeType ===1){
alert('元素節點:'+box.childNodes[i].nodeName);
//判斷是文本節點,輸出文本內容
}else if(box.childNodes[i].nodeType ===3){
alert('文本節點:'+box.childNodes[i].nodeValue);
}
}
具體代碼以下:
window.onload=function(){
var box = document.getElementById('box');
for(var i = 0 ; i < box.childNodes.length ; i++){
if(box.childNodes[i].nodeType===1){
alert('元素節點:'+box.childNodes[i].nodeName);
}else if(box.childNodes[i].nodeType===3){
alert('元素節點:'+box.childNodes[i].nodeValue);
}
}
}
PS:在獲取到文本節點的時候,是沒法使用innerHTML這個屬性輸出文本內容的,這個非標準的屬性必須在獲取
元素節點的時候,才能輸出裏面包含的文本。
alert(box.innerHTML); //innerHTML和nodeValue第一個區別
PS:innerHTML和nodeValue第一個區別,就是取值的。那麼第二個區別就是賦值的時候,nodeValue會把包含在
文本里的HTML轉義成特殊字符串,從而達到造成單純文本的效果。
box.childNodes[0].nodeValue = '<strong>abc</strong>'; //結果爲:<strong>abc</strong>
box.innerHTML = '<strong>abc</strong>'; //結果爲:abc
2.firstChild和lastChild屬性
firstChild用於獲取當前元素節點的第一個子節點,至關於childNodes[0];lastChild用戶獲取當前元素節點的最後
一個子節點,至關於childNodes[document.getElementById('box').childNodes.length-1]。
alert(box.fistChild.nodeName); //獲取第一個子節點的標籤名,#text,文本節點沒有標籤名
alert(box.lastChild.nodeName); //獲取最後一個子節點的標籤名,#text,文本節點沒有標籤名
alert(box.firstChild.nodeType); //3,獲取第一個子節點的屬性名
alert(box.lastChild.nodeType); //3,獲取最後一個子節點的屬性名
alert(box.fistChild.nodeValue); //獲取第一個子節點的文本內容
alert(box.lastChild.nodeValue); //獲取最後一個子節點的文本內容
3.ownerDocument屬性
ownerDocument屬性返回該節點的文檔對象根節點。返回的對象至關於document。
alert(box.ownerDocument === document); //true,根節點
4.parentNode、previousSibling、nextSibling屬性
parentNode屬性返回該節點的父節點,previousSibling屬性返回該節點的前一個同級節點,nextSibling屬性
則是返回該節點的後一個同級節點。
alert(box.parentNode.nodeName); //獲取父節點的標籤名
alert(box.lastChild.previousSibing); //獲取最後一個子節點的前一個同級節點
alert(box.firstChild.nextSibing); //獲取第一個子節點的後一個同級節點
alert(box.lastChild.previousSibing.nodeName); //獲取最後一個子節點的前一個同級節點的標籤名
5.attributes屬性
attributes屬性返回該節點的屬性節點集合。
PS:遍歷的時候是從後向前的
var box = document.getElementById('box');
alert(box.attributes); //NameNodeMap
alert(box.attributes.length); //返回屬性節點個數
alert(box.attributes[0]); //Attr,返回最後一個屬性節點
alert(box.attributes[0].nodeType); //2,返回節點類型
alert(box.attributes[0].nodeValue); //屬性值
alert(box.attributes['id']); //Attr,返回屬性爲id的節點
alert(box.attributes.getNamedItem('id')); //Attr
6.忽略空白文本節點
var body = document.getElementsByTagName('body')[0]; //獲取body元素節點
alert(body.childNodes.length); //獲得子節點個數,IE3個,非IE7個
PS:在非IE中,標準的DOM具備識別空白子節點的功能,因此在火狐瀏覽器是7個,而IE自動忽略了,若是要
保持一致的子元素節點,須要手工忽略掉它。
var box = document.getElementById('box');
filterSpaceNode(box.childNodes);
function filterSpaceNode(nodes){
var ret = [];
for(var i = 0 ; i < nodes.length ;i++){
//若是識別到空白文本節點,就不要添加數組
if(nodes[i].nodeType == 3 && /^\s+$/.test(nodes[i].nodeValue))continue;
//把每次的元素節點,添加到數組裏
ret.push(nodes[i]);
}
return ret;
}
PS:上面的方法,採用的忽略空白文本節點的方法,把獲得元素節點累加到數組裏返回。還有一種作法就是,
直接刪除空白爲文件節點便可。
function filterSpaceNode(nodes){
for(var i = 0 ; i < nodes.length ; i++){
if(nodes[i].nodeType == 3&&/^\s+$/.test(nodes[i].nodeType)){
//獲得空白節點以後,移到父節點上,刪除子節點
nodes[i].parentNode.removeChild(nodes[i]);
}
}
return nodes;
}
PS:若是firstChild、lastChild、previousSibling和nextSibling在獲取節點的過程當中遇到空白節點,咱們該怎麼
處理掉呢?
function removeWhiteNode(nodes){
for(var i = 0 ; i<nodes.childNodes.length ; i++){
if(nodes.childNodes[i].nodeType ===3 && /^\s+$/.text(nodes.childNodes[i].nodeValue)){
nodes.childNode[i].parentNode.removeChild(nodes.childNodes[i]);
}
}
return nodes;
}
4、節點操做
DOM不僅僅能夠查找節點,也能夠建立節點、複製節點、插入節點、刪除節點和替換節點。
節點操做方法
方法 說明
write() 這個方法能夠把任意字符串插入到文檔中
createElement() 建立一個元素節點
appendChild() 將新節點追加到子節點列表的末尾
createTextNode() 建立一個文件節點
insertBefore() 將新節點插入前面
repalceChild() 將新節點替換舊節點
cloneNode() 複製節點
removeChild() 移除節點
1.write()方法
write()方法能夠把任意字符串插入到文檔中去。
document.write('<p>這是一個段落</p>'); //輸出任意字符串
2.createElement()方法
createElement()方法能夠建立一個元素節點。
document.createElement('p'); //建立一個元素節點
3.appendChild()方法
appendChild()方法講一個新節點添加到某個節點的子節點列表的末尾上。
var box = document.getElementById('box'); //獲取某一個元素節點
var p = document.createElement('p'); //建立一個新元素節點<p>,只是建立一個新元素節點,尚未添加到文檔中去,只是駐留在內存中
box.appendChild(p); //把新元素節點<p>添加子節點末尾
4.createTextNode()方法
createTextNode()方法建立一個文本節點。
var text = document.createTextNode('段落'); //建立一個文本節點
p.appendChild(text); //將文本節點添加到子節點末尾
document.getElementsByName('body')[0].appendChild('測試Div');
5.insertBefore()方法
insertBefore()方法能夠把節點建立到指定節點的前面。
//box.parentNode就是body
box.parentNode.insertBefore(p,box); //把<div>以前建立一個節點
//在box的父節點添加一個p,就是在box前面添加一個元素節點
PS:insertBefore()方法能夠給當前元素的前面建立一個節點,但卻沒有提供給當前元素的後面建立一個節點,
那麼,咱們能夠用本身已有知識建立一個insertAfter()函數。
var box = document.getElementById('box');
var p = document.createElement('p');
insertAfter(p,box);
function insertAfter(newElement,targetElement){
//獲得父節點
var parent = targetElement.parentNode;
//若是最後一個子節點是當前元素,那麼直接添加便可
if(parent.lastChild === targetElement){
parent.appendChild(newElement);
}else{
//不然,在當前節點的下一個節點以前添加
parent.insertBefore(newElement.targetElement.nextSibing);
}
}
PS:createElement在建立通常元素節點的時候,瀏覽器的兼容性都還比較好。但在幾個特殊標籤上,好比iframe
、input中radio和checkbox、button元素中,可能會在IE6,7如下的瀏覽器存一些不兼容。
var input = null;
if(BrowserDelect.browser == 'Internet Explorer' && BrowserDelect.version <=7){
//判斷IE6,7,使用字符串的方式
input = document.createElement("<input type = \"radio\"name = \"sex\">");
}else{
//標準瀏覽器,使用標準方式
input = document.createElement('input');
input.setAttribute('type' , 'radio');
input.setAttribute('name' , 'sex');
}
document.getElementsByTagName('body')[0].appendChild(input);
6.repalceChild()方法
repalceChild()方法能夠把節點替換成指定的節點。
box.parentNode.repalceChild(p,box); //把<div>換成<p>
7.cloneNode()方法
cloneNode()方法能夠把子節點複製出來。
var box = document.getElementById('box');
var clone = box.firstChild.cloneNode(true); //得到第一個子節點,true表示複製內容
box.appendChild(clone); //添加到子節點
//克隆一個節點,若是是true就是把標籤內的文本一併克隆,若是是false只克隆標籤。
var box = document.getElementById('box');
var clone = removeWhiteNode(box).firstChild.cloneNode(true);//得到第一個子節點,true表示複製內容
box.appendChild(clone); //添加到子節點
//移除空白節點
function removeWhiteNode(nodes){
for(var i = 0 ; i<nodes.childNodes.length ; i++){
if(nodes.childNodes[i].nodeType ===3 && /^\s+$/.text(nodes.childNodes[i].nodeValue)){
nodes.childNode[i].parentNode.removeChild(nodes.childNodes[i]);
}
}
return nodes;
}
8.removeChild()方法removeChild()方法能夠把box.parentNode.removeChild(box); //刪除指定節點