5. DOM
5.1 document對象
5.1.1 DOM的含義
文檔對象模型(Document Object Model)捧韵。
5.1.2 document對象概述
document對象是文檔的根節(jié)點遮精,window.document屬性就指向它。
document.childNodes屬性返回該對象的所有子節(jié)點邮丰。
一般來說,document對象的第一個子節(jié)點是document.doctype,第二個子節(jié)點是document.documentElement。
5.1.3 document對象的屬性
5.1.3.1 文檔信息屬性
title:文檔的標(biāo)題糟红。
lastModified:文檔文件的上一次修改時間。
referrer:文檔的訪問來源乌叶。
URL:文檔的URL。
5.1.3.2 指向其他節(jié)點或?qū)ο蟮膶傩?/h4>
doctype:文檔類型節(jié)點柒爸。
documentElement:html元素節(jié)點准浴。
head:head元素節(jié)點。
body:body元素節(jié)點捎稚。
5.1.3.3 指向特定元素集合的屬性
document.forms :所有的form元素乐横。
document.images:所有的img元素求橄。
document.links:所有的a元素。
document.scripts:所有的script元素葡公。
document.styleSheets:所有的link或者style元素罐农。
5.1.3.4 implementation屬性
doctype:文檔類型節(jié)點柒爸。
documentElement:html元素節(jié)點准浴。
head:head元素節(jié)點。
body:body元素節(jié)點捎稚。
document.forms :所有的form元素乐横。
document.images:所有的img元素求橄。
document.links:所有的a元素。
document.scripts:所有的script元素葡公。
document.styleSheets:所有的link或者style元素罐农。
該屬性指向一個對象,提供瀏覽器支持的模塊信息催什,它的hasFeature方法返回一個布爾值涵亏,表示是否支持某個模塊。
document.implementation.hasFeature('MutationEvents','2.0') // true
5.1.4 document對象的方法
5.1.4.1 document.write()
document.write方法用于向頁面寫入內(nèi)容蒲凶。如果在頁面已經(jīng)渲染完成的情況下調(diào)用這個方法气筋,會把原有的頁面全部抹去,等于是在一個新建的頁面上寫入內(nèi)容旋圆。
所以宠默,一般document.write只能在頁面渲染的過程中使用。
<div>
<script type="text/javascript">
document.write("<h1>Main title</h1>")
</script>
</div>
5.1.4.2 querySelector()灵巧,getElementById()
querySelector使用CSS選擇器語法(還可以接受復(fù)雜的CSS選擇器)搀矫,
getElementById使用id屬性(更高效)。
找不到返回null刻肄。
document.querySelector('#myElement')
document.getElementById('myElement')
5.1.4.2 querySelectorAll()艾君,getElementsByTagName(),getElementsByClassName()
document.querySelectorAll('DIV:not(.ignore)');
document.getElementsByTagName('li')
document.getElementsByClassName('liClass')
5.1.4.3 getElementsByName()
用于選擇擁有name屬性的HTML元素肄方,比如form冰垄、img、frame权她、embed和object虹茶。返回值是一組對象。
var forms = document.getElementsByName("x");
forms[0].tagName // "FORM"
5.1.4.4 createElement()隅要,createTextNode()
createElement方法用來生成元素節(jié)點蝴罪,參數(shù)是元素節(jié)點的tagName屬性
createTextNode方法用來生成文本節(jié)點。參數(shù)是要生成的文本節(jié)點的內(nèi)容步清。
var elementNode = document.createElement('div');
var textNode = document.createTextNode('Hi');
5.1.4.5 hasFocus()
返回布爾值要门,表示當(dāng)前文檔之中是否有元素被激活或獲得焦點鸥跟。
focused = document.hasFocus();
5.2 Node對象
5.2.1 Node節(jié)點對象
DOM就是由Node組成的改备。Node分外:
- DOCUMENT_NODE 文檔節(jié)點(window.document)觉渴、
- ELEMENT_NODE 元素節(jié)點预愤、
- ATTRIBUTE_NODE 屬性節(jié)點(比如class="right")角虫、
- TEXT_NODE 文本節(jié)點池户、
- DOCUMENT_FRAGMENT_NODE 文檔碎片節(jié)點
- DOCUMENT_TYPE_NODE 文檔類型節(jié)點黎比。
瀏覽器原生提供一個Node對象斩郎,上面所有類型的節(jié)點都是Node對象派生出來的第步,它們都繼承了Node的屬性和方法疮装。
對于HTML文檔缘琅,節(jié)點有以下類型:
5.2.1.1 Node對象的屬性
1、nodeName屬性和nodeType屬性
nodeName節(jié)點的名稱廓推,nodeType節(jié)點的常數(shù)值刷袍。
類型 | nodeName | nodeType |
---|---|---|
ELEMENT_NODE | 大寫的HTML元素名 | 1 |
ATTRIBUTE_NODE | 等同于Attr.name | 2 |
TEXT_NODE | #text | 3 |
2、nodeValue屬性
Text節(jié)點的nodeValue屬性返回文本內(nèi)容樊展,其他的節(jié)點都返回null呻纹。
3、childNodes屬性和children屬性
childNodes返回所有子節(jié)點
children返回成員為HTML元素類型的子節(jié)點
4滚局、指向其他節(jié)點的屬性
firstChild:第一個子節(jié)點居暖。
lastChild:最后一個子節(jié)點。
藤肢。太闺。。
5.2.1.2 Node對象的方法
appendChild()
cloneNode()
compareDocumentPosition()
contains()
hasChildNodes()
insertBefore()
isEqualNode()
removeChild()
replaceChild()
5.2.2 Element對象
5.2.2.1 屬性
每個HTML標(biāo)簽嘁圈,都會轉(zhuǎn)化成一個Element對象節(jié)點省骂。
所有的Element節(jié)點的nodeType屬性都是1,但是不同標(biāo)簽生成的節(jié)點是不一樣的最住。
1钞澳、innerHTML屬性,outerHTML屬性涨缚,textContent屬性轧粟,innerText屬性,outerText屬性
2脓魏、tagName屬性
tagName屬性返回該節(jié)點的HTML標(biāo)簽名兰吟,與nodeName屬性(大寫)相同。
document.querySelector('a').tagName // A
3茂翔、attributes屬性
var atts = document.querySelector('a').attributes;
for(var i=0; i< atts.length; i++){
console.log(atts[i].nodeName +'='+ atts[i].nodeValue);
}
5.2.2.2 className屬性和classList屬性
都返回HTML元素的class屬性混蔼。
<div class="one two three" id="myDiv"></div>
document.getElementById('myDiv').className
// "one two three"
document.getElementById('myDiv').classList
// {
// 0: "one"
// 1: "two"
// 2: "three"
// length: 3
// }
classList對象有一系列方法。
add():增加一個class珊燎。
remove():移除一個class惭嚣。
contains():檢查該DOM元素是否包含某個class。
toggle():將某個class移入或移出該DOM元素悔政。
item():返回列表中某個特定位置的class晚吞。
toString():將class的列表轉(zhuǎn)為字符串。
比較className和classList寫法的區(qū)別卓箫。
document.getElementById('foo').className += 'bold';
document.getElementById('foo').classList.add('bold');
document.getElementById('foo').classList.remove('bold');
document.getElementById('foo').className =
document.getElementById('foo').className.replace(/^bold$/, '');
5.2.2.3 html元素
html元素是網(wǎng)頁的根元素载矿,document.documentElement就指向它。
1烹卒、clientWidth屬性闷盔,clientHeight屬性
返回視口(用戶當(dāng)前能夠看見的那部分,不包括滾動條)的大小旅急。
他兩基本上與window.innerWidth和window.innerHeight同義逢勾。只有一個區(qū)別,后者包括了滾動條藐吮。
(2)offsetWidth屬性溺拱,offsetHeight屬性
這兩個屬性返回html元素的寬度和高度,即網(wǎng)頁的總寬度和總高度谣辞。
5.2.2.4 dataset屬性
dataset屬性用于操作HTML標(biāo)簽的data-*屬性迫摔。
<div id="myDiv" data-id="myId"></div>
var id = document.getElementById("myDiv").dataset.id;
document.getElementById("myDiv").dataset.id = "hello"; //賦值或添加
delete document.getElementById("myDiv").dataset.id //刪除
注意:dataset屬性使用駱駝拼寫法表示屬性名,這意味著data-hello-world會用dataset.helloWorld表示泥从。而如果此時存在一個data-helloWorld屬性句占,該屬性將無法讀取。
5.2.2.5 頁面位置相關(guān)屬性
1躯嫉、offsetParent屬性纱烘、offsetTop屬性和offsetLeft屬性
2、clientWidth屬性和clientHeight屬性
3祈餐、scrollHeight屬性和scrollWidth屬性
4擂啥、scrollTop屬性和scrollLeft屬性
5.2.2.6 style屬性
style屬性用來讀寫頁面元素的行內(nèi)CSS屬性,詳見 5.4
5.2.2.7 Element對象的方法
略
5.2.2.8 setAttribute()帆阳,removeAttribute()
<div id="foo"></div>
document.getElementById('foo').setAttribute('role', 'button');
//<div id="foo" role="button"></div>
document.getElementById('foo').removeAttribute('role');
5.2.2.9 insertAdjacentHTML()
將一段字符串哺壶,作為HTML或XML對象,插入DOM蜒谤。通常用這個方法添加新節(jié)點山宾。
document.getElementById("box2").insertAdjacentHTML('beforebegin', '<div><p>This gets inserted.</p></div>');
第一個是插入的位置,第二個是插入的節(jié)點字符串芭逝。
關(guān)于插入的位置塌碌,可以取值:beforebegin、afterbegin旬盯、beforeend台妆、afterend。
5.2.2.10 getBoundingClientRect方法
略
5.2.2.11 table元素
表格有一些特殊的DOM操作方法胖翰。
insertRow():在指定位置插入一個新行(tr)接剩。
deleteRow():在指定位置刪除一行(tr)。
insertCell():在指定位置插入一個單元格(td)萨咳。
deleteCell():在指定位置刪除一個單元格(td)懊缺。
5.2.3 Text節(jié)點
文本對應(yīng)Text節(jié)點,哪怕只有一個空格,也會形成文本節(jié)點鹃两。
5.3 DOM事件
5.3.1 概述
DOM定義了一些事件遗座,并且允許開發(fā)者通過以下3個方式指定事件的回調(diào)函數(shù)。
1俊扳、HTML屬性定義
<body onclick="console.log('觸發(fā)事件')">
2途蒋、Element對象的事件屬性
div.onclick = function(event){
console.log('觸發(fā)事件');
};
3、addEventListener方法馋记,removeEventListener方法
button.addEventListener('click',
function(){console.log('Hello world');},
false);
其中第3個參數(shù)默認為false号坡,表示回調(diào)函數(shù)只在冒泡階段被觸發(fā)。
5.3.2 事件的傳播
5.3.2.1 傳播的三個階段
第一階段:從文檔的根元素(html元素)傳導(dǎo)到目標(biāo)元素梯醒,稱為“捕獲階段”宽堆。
第二階段:在目標(biāo)元素上觸發(fā),稱為“目標(biāo)階段”茸习。
第三階段:從目標(biāo)元素傳導(dǎo)回文檔的根元素畜隶,稱為“冒泡階段”。
瀏覽器總是假定click事件的目標(biāo)對象逮光,是嵌套最深的那個元素代箭。
5.3.2.2 事件的代理
由于事件有冒泡階段,因此可以把子元素的回調(diào)函數(shù)定義在父元素上統(tǒng)一處理涕刚。這種方法叫做事件的代理嗡综。
var ul = document.querySelector('ul');
ul.addEventListener('click', function(event) {
if (event.target.tagName.toLowerCase() === 'li') {
// some code
}
});
5.3.3 事件的類型
DOM支持多種事件。
5.3.3.1 用戶界面事件
1杜漠、load事件极景,error事件
對資源的加載,成功了觸發(fā)load事件驾茴,失敗了觸發(fā)error事件盼樟。
error事件不會冒泡。以防止引發(fā)父元素的error事件回調(diào)函數(shù)锈至。
2晨缴、unload事件
卸載資源時觸發(fā)。
3峡捡、beforeunload事件
在用戶關(guān)閉網(wǎng)頁時觸發(fā)击碗。它會自動跳出一個確認對話框,如果用戶點擊“取消”按鈕们拙,網(wǎng)頁就不會關(guān)閉稍途。
window.onbeforeunload = function() {
if (textarea.value != textarea.defaultValue) {
return '你確認要離開嗎?';
}
};
4砚婆、resize事件
改變?yōu)g覽器窗口大小時觸發(fā)械拍。
5、abort事件
資源在加載成功前停止加載時觸發(fā)該事件,主要發(fā)生在element坷虑、XMLHttpRequest甲馋、XMLHttpRequestUpload對象。
6猖吴、scroll事件
用戶滾動窗口或某個元素時觸發(fā)該事件摔刁,主要發(fā)生在element挥转、document海蔽、window對象。
7绑谣、contextmenu事件
用戶鼠標(biāo)右擊某個元素時觸發(fā)党窜,主要發(fā)生在element對象。
5.3.3.2 焦點事件
事件名稱 | 涵義 | 事件的目標(biāo) | |
---|---|---|---|
blur | 元素喪失焦點 | Element(除了body和frameset元素) | Document |
focus | 元素獲得焦點 | Element(除了body和frameset元素) | Document |
focusin | 元素即將獲得焦點借宵,在focus之前觸發(fā) | Element | |
focusout | 元素即將喪失焦點幌衣,在blur之前觸發(fā) | Element |
5.3.3.3 表單事件
1、change事件
一些特定的表單元素(比如文本框和輸入框)失去焦點壤玫、并且值發(fā)生變化時觸發(fā)豁护。
2、reset事件
表單重置(reset)時觸發(fā)欲间。
3楚里、submit事件
表單提交(submit)時觸發(fā)。
4猎贴、select事件
用戶在文本框或輸入框中選中文本時觸發(fā)班缎。
5.3.3.4 鼠標(biāo)事件
1、click事件
它的定義是同一個位置完成一次mousedown和mouseup動作她渴。它們的觸發(fā)順序是:mousedown达址,mouseup,最后click趁耗。
可以利用click事件進行CSRF(跨站請求偽造Cross-site request forgery)攻擊沉唠。
2、dblclick事件
用戶在element苛败、document满葛、window對象上用鼠標(biāo)雙擊時觸發(fā)。該事件會在mousedown著拭、mouseup纱扭、click之后觸發(fā)。
3儡遮、mousedown事件
4乳蛾、mouseup事件
5、mouseenter事件
該事件與mouseover事件相似,區(qū)別在于mouseenter事件不會冒泡肃叶,而且當(dāng)鼠標(biāo)移出子元素的邊界蹂随、當(dāng)仍在父元素之中時,它不會在父元素上觸發(fā)因惭。
6岳锁、mouseleave事件
該事件與mouseout事件類似,區(qū)別在于mouseleave事件不會冒泡蹦魔,而且要等到鼠標(biāo)離開該元素本身和它的所有子元素時才觸發(fā)激率。
7、mousemove事件
當(dāng)鼠標(biāo)持續(xù)移動時勿决,該事件會連續(xù)觸發(fā)乒躺。(性能)
8、mouseout事件
9低缩、mouseover事件
10嘉冒、wheel事件
用戶滾動鼠標(biāo)的滾輪時觸發(fā)。
5.3.3.5 鍵盤事件
1咆繁、keydown事件
2讳推、keypress事件
用戶按下某個鍵時觸發(fā)。如果用戶一直按著玩般,這個事件就持續(xù)觸發(fā)银觅。
3、keyup事件
//捕捉用戶按下Ctrl+H鍵的代碼
document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.which === 72) {
// open help widget
}
});
5.3.3.6 document對象的特有事件
1壤短、readystatechange
在readyState屬性發(fā)生變化時觸發(fā)设拟。它的發(fā)生對象是document和XMLHttpRequest對象。
2久脯、DOMContentLoaded
在網(wǎng)頁解析完成時觸發(fā)纳胧,此時各種外部資源(resource)還沒有被完全下載。也就是說帘撰,這個事件比load的觸發(fā)早得多跑慕。
5.3.3.7 拖拉事件
1、drag
drag事件在源對象被拖拉過程中觸發(fā)摧找。
2核行、dragstart,dragend
dragstart事件在用戶開始用鼠標(biāo)拖拉某個對象時觸發(fā)蹬耘,dragend事件在結(jié)束拖拉時觸發(fā)芝雪。
3、dragenter综苔,dragleave
dragenter事件在源對象拖拉進目標(biāo)對象后惩系,在目標(biāo)對象上觸發(fā)位岔。dragleave事件在源對象離開目標(biāo)對象后,在目標(biāo)對象上觸發(fā)堡牡。
4抒抬、dragover事件
dragover事件在源對象拖拉過另一個對象上方時,在后者上觸發(fā)晤柄。
5擦剑、drop事件
當(dāng)源對象被拖拉到目標(biāo)對象上方,用戶松開鼠標(biāo)時芥颈,在目標(biāo)對象上觸發(fā)drop事件惠勒。
5.3.3.8 CSS事件
transitionEnd
animationstart,animationend浇借,animationiteration
5.3.4 event對象
當(dāng)事件發(fā)生以后捉撮,會生成一個事件對象event,在DOM中傳遞妇垢,也被作為參數(shù)傳給回調(diào)函數(shù)。
IE8及以下版本肉康,這個事件需要通過window對象的event屬性讀取闯估,所以要獲取這個對象,往往寫成下面這樣吼和。
function myEventHandler(event) {
var actualEvent = event || window.event;
// handle actualEvent
}
5.3.4.1 event對象的屬性
type:返回一個字符串涨薪,表示事件的名稱。
target:返回一個Element節(jié)點炫乓,表示事件起源的那個節(jié)點刚夺。
keyCode:返回按鍵對應(yīng)的ASCII碼。
ctrlKey:返回一個布爾值末捣,表示是否按下ctrl鍵侠姑。
5.3.4.2 click事件
click的event還包括:
pageX,pageY:點擊位置相對于html元素的坐標(biāo)箩做,單位為CSS像素莽红。
clientX,clientY:點擊位置相對于視口(viewport)的坐標(biāo)邦邦,單位為CSS像素安吁。
screenX,screenY:點擊位置相對于設(shè)備顯示屏幕的坐標(biāo)燃辖,單位為設(shè)備硬件的像素鬼店。
5.3.4.3 event對象的方法
略
5.3.5 自定義事件
用戶還可以自定義事件,然后手動觸發(fā)黔龟。
$('some-element').trigger('my-custom-event');
這是jQuery定義的trigger事件妇智,它會層層向上冒泡确沸。冒泡過程中,如果有一個元素定義了該事件的回調(diào)函數(shù)俘陷,該回調(diào)函數(shù)就會觸發(fā)罗捎。
也可以使用瀏覽器原生方法創(chuàng)造自定義事件。
5.4 CSS操作
5.4.1 DOM元素的CSS操作
5.4.1.1 HTML元素的style屬性
操CSS的最簡單方法:通過DOM的getAttribute拉盾、setAttribute和removeAttribute方法桨菜。
div.setAttribute('style','background-color:red;');
5.4.1.2 style對象
DOM還提供style屬性,指向一個對象(簡稱style對象)捉偏,用來讀寫元素的行內(nèi)CSS樣式倒得。
var divStyle = document.querySelector('div').style;
divStyle.backgroundColor = 'red';
divStyle.width = '100px';
1、style對象的屬性名
它等于:去掉CSS規(guī)則名的橫杠夭禽,橫杠后的第一個字母大寫霞掺。
如:background-color 改為 backgroundColor。
如果CSS規(guī)則名是js保留字讹躯,則改為“css”+規(guī)則名菩彬。如:float 改為 cssFloat。
注意潮梯,style對象的屬性值都是字符串且包括單位骗灶。所以,divStyle.width不能設(shè)置為100秉馏,而要設(shè)置為'100px'耙旦。
2、style對象的cssText屬性
用來讀寫或刪除整個style屬性萝究。
divStyle.cssText = 'background-color:red;height:100px;width:100px;';
3免都、CSS模塊的偵測
“CSS模塊的偵測”是判斷當(dāng)前瀏覽器是否支持某個模塊。
常用方法是帆竹,判斷DOM元素的style對象的某個屬性值是否為字符串绕娘。
typeof element.style.animationName === 'string';
typeof element.style.transform === 'string';
有時候,需要把不同瀏覽器的CSS規(guī)則前綴也考慮進去馆揉。
typeof document.getElementById("content").style['-webkit-animation'] === 'string'
4业舍、style對象的方法
setPropertyValue(propertyName,value) // 寫
getPropertyValue(propertyName) // 讀
removeProperty(propertyName) // 刪除
5、style對象的animation-play-state屬性
用來控制暫停動畫的播放升酣。該屬性需要加上瀏覽器前綴舷暮。
element.style.webkitAnimationPlayState = "paused";
element.style.webkitAnimationPlayState = "running";
5.4.1.3 CSS偽元素
CSS偽元素是通過CSS向DOM添加的元素,主要方法是通過“:before”和“:after”生成偽元素噩茄,然后用content屬性指定偽元素的內(nèi)容下面。
5.4.1.4 CSS事件
動畫(animation)事件
過渡(transition)事件
5.4.2 樣式表
5.4.2.1 獲取樣式表
document對象的styleSheets屬性,包含一個類似數(shù)組的對象绩聘,里面是當(dāng)前文檔所有的link元素(指向樣式表)和style元素沥割。
var sheets = document.styleSheets;
var sheet = document.styleSheets[0];
5.4.2.2 樣式表對象
樣式表對象有許多屬性和方法耗啦。
cssRules屬性指向一個類似數(shù)組的對象,它的每個成員就是一條CSS規(guī)則机杜,其cssText屬性就是CSS規(guī)則的字符串帜讲。
var sheet = document.querySelector('#styleElement').sheet;
sheet.cssRules[0].cssText
// "body { background-color: red; margin: 20px; }"
insertRule和deleteRule方法 用于插入和刪除CSS規(guī)則。
disabled屬性 用于打開或關(guān)閉一張樣式表椒拗。
5.4.2.3 添加樣式表
添加內(nèi)置樣式表似将,就是在文檔中添加style節(jié)點。
添加外部樣式表蚀苛,就是在文檔中添加link節(jié)點在验。
var linkElm = document.createElement('link');
linkElm.setAttribute('type', 'text/css');
linkElm.setAttribute('href', 'reset-min.css');
document.head.appendChild(linkElm);
5.4.3 window.getComputedStyle方法
getComputedStyle方法返回一個HTML元素的最終樣式信息的對象。
5.5 拖放操作
5.5.1 拖放操作
5.5.1.1 網(wǎng)頁元素的draggable屬性
draggable用于標(biāo)識元素是否可以拖動堵未。
在大多數(shù)瀏覽器中腋舌,a元素和img元素默認是可以拖放的。
5.5.1.2 事件
略
5.5.2 自定義網(wǎng)頁元素(Custom Element)
通過JavaScript可以自定義網(wǎng)頁元素渗蟹。使用前块饺,用document對象的registerElement方法登記該元素。
5.6 Mutation Observer
Mutation Observer(變動觀察器)是監(jiān)視DOM變動的接口拙徽。當(dāng)DOM對象樹發(fā)生任何變動的時候刨沦,Mutation Observer會得到通知。
它與事件有一個本質(zhì)不同:事件是同步觸發(fā)膘怕;Mutation Observer則是異步觸發(fā)。