JS DOM(2017.12.28)
一.獲得元素節點的方法
document.getElementById() 根據Id獲取元素節點
document.getElementsByName() 根據name獲取元素節點 遍歷出來的是一個數字
document.getElementsByTagName() 根據HTML標簽名獲取元素節點,註意選擇器返回的是一個NodeList對象,能根據索引號選擇其中1個,可以遍歷輸出。
document.getElementsByClassName() 根據class獲取元素節點
二、節點關系
(1)作為節點數的文檔
1、parentNode 獲取該節點的父節點
2、childNodes 獲取該節點的子節點數組
3、firstChild 獲取該節點的第一個子節點
4、lastChild 獲取該節點的最後一個子節點
5、nextSibling 獲取該節點的下一個兄弟元素
6、previoursSibling 獲取該節點的上一個兄弟元素
7、nodeType 節點的類型,9代表Document節點,1代表Element節點,3代表Text節點,8代表Comment節點,11代表DocumentFragment節點
8、nodeVlue Text節點或Comment節點的文本內容
9、nodeName 元素的標簽名(如P,SPAN,#text(文本節點),DIV),以大寫形式表示
(2)作為元素樹的文檔
1、firstElementChild 第一個子元素節點
2、lastElementChild 最後一個子元素節點
3、nextElementSibling 下一個兄弟元素節點
4、previousElementSibling 前一個兄弟元素節點
5、childElementCount 子元素節點個數量
註意,此5個方法文本節點不算進去
三、節點操作:創建,插入,刪除節點
1、document.createTextNode() 創建一個文本節點
2、document.createElement() 創建一個元素節點,這個方法只接受一個參數,即要創建元素的標簽名。這個標簽名在HTML
文檔中不區分大小寫,在XHTML
中區分大小寫。
3、插入節點
appendChild() //將一個節點插入到調用節點的最後面
insertBefore() //接受兩個參數,第一個為待插入的節點,第二個指明在哪個節點前面,如果不傳入第二個參數,則跟appendChild一樣,放在最後。
insertAfter() //可以自己創建一個在指定節點後面插入節點的函數,代碼如下:
1 function insertAfter(newElement,targetElement){ 2 var parent = targetElement.parentNode; 3 if(parentNode.lastChild == targetElement){ 4 parent.appendChild(newElement); 5 } 6 else{parent.insertBefore(newElement,targetElement.nextSibling) 7 } 8 }
4、刪除和替換節點。
1、removeChild(); 由父元素調用,刪除一個子節點。註意是直接父元素調用,刪除直接子元素才有效,刪除孫子元素就沒有效果了。該方法移除節點,接受一個參數,即要移除的節點,同時該方法返回被移除的節點。只能是一個節點,不能是一組節點。
2、replaceChild() //刪除一個子節點,並用一個新節點代替它,第一個參數為新建的節點,第二個節點為被替換的節點
5、document.write()可以方便快捷的把字符串插入到文檔中。
四、屬性操作
1.
setAttribute()
添加一個新屬性(attribute
)到元素上,或改變元素上已經存在的屬性的值。註意:在IE7
下,修改了元素的class
,如果已有class
,則會出現兩個class
,通過setAttribute()
添加的不生效;如果沒有class
,則添加上class
,但這個添加上去的class
的樣式不會生效。
2.
removeAttribute()
該方法用於移除元素的屬性。
3.
getAttribute()
該方法返回元素上指定屬性(attribute
)的值。如果指定的屬性不存在,則返回 null
或 ""
(空字符串)(IE5+
都返回null
)。註意:IE7
下不能正確返回class
,返回的是null
,其他正常。
4.
hasAttribute()
hasAttribute()
返回一個布爾值,指示該元素是否包含有指定的屬性(attribute
)。註意:IE7
不支持該方法。
5.
自定義屬性
data-*
html5
裏有一個data-*
去設置獲取元素的自定義屬性值。
<div id="div1" data-aa="11">
利用div1.dataset
可以獲得一個DOMStringMap
,包含了元素的所有data-*
。
使用div1.dataset.aa
就可以獲取11
的值。
同樣,通過設置div1.dataset.bb = "22"
就可以設置一個自定義屬性值。
在不兼容的瀏覽器裏,就使用getAttribute
和setAttribute
五、事件
四、共享onload事件
function addLoadevent(func) {
var oldonload = window.onload;
if(typeof window.onload !=‘ function‘){
window.onload = func;
}else{
window.onload = function(){
func;
oldonload;
}
}
}
addEventListener()
addEventListener()
將指定的事件監聽器註冊到目標對象上,當目標對象觸發制定的事件時,指定的回調函數就會觸發。目標對象可以是 文檔上的元素、 document、 window
或者XMLHttpRequest
(比如onreadystatechange
事件)。
IE8
及以下不支持此方法且只有事件冒泡沒有事件捕獲。IE9
開始支持此方法,也就有了事件捕獲。
var div1 = document.getElementById("div1");
div1.addEventListener("click", listener, false);
function listener() {
console.log(‘test‘);
}
var cloneHtml = div1.cloneNode(true);
document.body.appendChild(cloneHtml);
第一個參數是事件名,第二個是回調函數,第三個參數為true
表示捕獲,false
表示冒泡。
var div1 = document.getElementById("div1");
div1.addEventListener("click", listener1, true/fasle);
function listener1() {
console.log(‘test1‘);
}
var div2 = document.getElementById("div2");
div2.addEventListener("click", listener2, true/fasle);
function listener2() {
console.log(‘test2‘);
}
有一點要註意的是,當對某一個元素1
既綁定了捕獲事件,又綁定了冒泡事件時:
當這個元素1
並不是觸發事件的那個元素2
時,則觸發順序會按照先 捕獲 後 冒泡 的順序觸發;
當這個元素1
就是最底層的觸發事件的元素時,則這個元素沒有捕獲和冒泡的區別,誰先綁定就先觸發誰。
var div2 = document.getElementById("div2");
div2.addEventListener("click", listener2, true);
function listener2() {
console.log(‘test2‘);
}
div2.addEventListener("click", listener1, false);
function listener1() {
console.log(‘test1‘);
}
// 按綁定順序執行,兩個`addEventLister()`顛倒過來則執行順序也變化
// 如果再對`div1`綁定一個捕獲、一個冒泡,則會先觸發捕獲 再 觸發冒泡,與綁定順序無關
removeEventListener()
與addEventListener()
綁定事件對應的就是移除已綁定的事件。第三個參數的布爾值代表解綁的是捕獲事件還是冒泡事件。兩個事件互不相關。
var div2 = document.getElementById("div2");
div2.addEventListener("click", listener2, true);
function listener2() {
console.log(‘test2‘);
}
div2.removeEventListener("click", listener2, true);
註意:只能通過removeEventListener()
解綁有名字的函數,對於綁定的匿名函數無法解除綁定。
div2.addEventListener("click", function(){
console.log(‘test‘);
console.log(this);
}, true);
div2.removeEventListener("click", function() {
console.log("test");
}, true);
div2.onclick = null;
// 點擊div2依然打印出test
註意:這裏this
指向觸發事件的元素自身。
attachEvent()、detachEvent()
IE8
及以下使用這兩個方法綁定和解綁事件,當然,IE9+
也支持這個事件。但這個方法綁定的事件默認為冒泡也只有冒泡。
// 這裏需要在事件前加 on
div2.attachEvent("onclick", listener1);
function listener1() {
console.log(‘test‘);
console.log(this);
}
div2.detachEvent("onclick", listener1);
和addEventListener()
一樣,也不能解綁匿名函數。
註意:這裏this
指向 window
。
阻止默認事件和冒泡
標準事件和IE
事件中的阻止默認事件和冒泡事件也有很大區別。
var div2 = document.getElementById("div2");
if (div2.addEventListener) {
div2.addEventListener("click", function(e) {
e.preventDefault(); // 阻止默認事件
e.stopPropagation(); // 阻止冒泡
console.log(e.target.innerHTML);
}, false);
} else {
div2.attachEvent("onclick", function() {
var e = window.event;
e.returnValue = false; // 阻止默認事件
e.cancelBubble = true; // 阻止冒泡
console.log(e.srcElement.innerHTML);
});
}
IE8
及以下的event
是綁定在window
上的。(我的IE11
裏,仿真到IE7
、IE8
也可以取到標準事件裏的 e
對象,估計是升級到IE11
的原因)。
自定義事件:
createEvent()
createEvent()
用於創建一個新的 event
,而後這個 event
必須調用它的 init()
方法進行初始化。最後就可以在目標元素上使用dispatchEvent()
調用新創建的event
事件了。
createEvent()
的參數一般有:UIEvents、MouseEvents、MutationEvents、HTMLEvents、Event(s)
等等,分別有對應的init()
方法。HTMLEvents、Event(s)
對應的都是initEvent()
方法。
initEvent(type, bubbles, cancelable)
type
表示自定義的事件類型,bubbles
表示是否冒泡,cancelable
表示是否阻止默認事件。
target.dispatchEvent(ev)
target
就是要觸發自定義事件的DOM
元素
var div1 = document.getElementById("div1");
div1.addEventListener("message", function(){
console.log(‘test‘);
}, false);
var div2 = document.getElementById("div2");
div2.addEventListener("message", function(e){
console.log(this);
console.log(e);
}, false);
var ev = document.createEvent("Event");
ev.initEvent("message", false, true); // 起泡參數變為true,div1的事件就會觸發
div2.dispatchEvent(ev);
六.獲取元素相關計算後的值
getComputedStyle()、currentStyle()
當我們想獲取元素計算後實際呈現在頁面上的各個值,就用這兩個方法。IE8
及以下用currentStyle()
,IE9+
及其他標準瀏覽器用getComputedStyle()
。
var div2 = document.getElementById("div2");
var result = "";
if (window.getComputedStyle) {
result = (window || document.defaultView).getComputedStyle(div2, null)[‘cssFloat‘];
} else {
result = div2.currentStyle["styleFloat"];
}
console.log(result);
// document.defaultView返回document對象所關聯的window
這兩個方法在不同的瀏覽器裏差距也很大。
比如float
屬性:getComputedStyle
: IE9
以上需要用cssFloat
,其他標準的用float
currentStyle
: IE8
及以下可用styleFloat
或者float
。
比如height
屬性:
假如未設置height
值,標準瀏覽器裏能計算出高度值,而currentStyle
計算出來是auto
。
上面的例子getComputedStyle
是用鍵值去訪問的,也可用getPropertyValue()
去訪問。(IE8
、IE7
不支持)
result = (window || document.defaultView).getComputedStyle(div2, null).getPropertyValue("float");
getBoundingClientRect()、getClientRects()
getBoundingClientRect
()該方法獲得頁面中某個元素的上、右、下、左分別相對瀏覽器視窗的位置。getBoundingClientRect
是DOM
元素到瀏覽器可視範圍的距離(到瀏覽器頂部而不是文檔頂部)。該函數返回一個Object
對象,該對象有6
個屬性:top,lef,right,bottom,width,height
;這裏的top、left
和css
中的理解很相似,width、height
是元素自身的寬高,但是right
,bottom
和css
中的理解有點不一樣。right
是指元素右邊界距窗口最左邊的距離,bottom
是指元素下邊界距窗口最上面的距離。
getClientRects()
是返回一個ClientRectList
集合。
var div1 = document.getElementById("div1");
var rects1 = div1.getClientRects();
var rects2 = div1.getBoundingClientRect();
console.log(rects1[0].top);
console.log(rects2.top);
JS DOM(2017.12.28)