JavaScript DOM筆記
DOM概念
文件物件模型(Document Object Model,簡稱DOM),是W3C組織推薦的處理可擴充套件標誌語言的標準程式設計介面。在網頁上,組織頁面(或文件)的物件被組織在一個樹形結構中,用來表示文件中物件的標準模型就稱為DOM。 **注意:**IE中的多有DOM物件都是以COM物件的形式實現的。 文件:把一個html檔案看成是一個文件,由於萬物皆物件,所有把這個文件看成是一個物件。 html:展示資訊,展示資料的。 xml:側重於儲存資料。 元素element:頁面中的所有的標籤都是元素,元素都可以看成是物件。 節點node:頁面中所有的內容都是節點:標籤,屬性,文字。 DOM又稱為文件樹模型
技巧
- 如果是迴圈的方式新增事件,推薦用命名函式。
- 如果不是迴圈的方式新增事件,推薦使用匿名函式。
btn.onclick = function() {
}
- return false可以阻止a跳轉
- 在表單中value和innerText都可修改文字內容。推薦第一種。
事件
事件:觸發-響應機制 Event介面表示在DOM中發生的任何事件,一些是使用者生成的(例如滑鼠或鍵盤事件),而其他由API生成。
事件三要素
- 事件源:觸發(被)事件的元素
- 事件型別:事件的觸發方式(例如滑鼠點選或鍵盤點選)
- 事件處理程式:事件觸發後要執行的程式碼(函式形式)
節點層次
Node型別
除了IE之外,在其他所有瀏覽器中都可以訪問到這個型別。JavaScript中的所有節點型別都是繼承自Node型別,因此所有節點型別都共享著相同的基本屬性和方法。 每個節點都有一個nodeType屬性,用於表明節點的型別。
- Node.ELEMENT_NODE(1)
- Node.ATTRIBUTE_NODE(2)
- Node.TEXT_NODE(3)
- Node.CDATA_SECTION_NODE(4)
- Node.ENTITY_REFERENCE_NODE(5)
- Node.ENTITY_NODE(6)
- Node.PROCESSING_INSTRUCTION_NODE(7)
- Node.COMMENT_NODE(8)
- Node.DOCUMENT_NODE(9)
- Node.DOCUMNET_TYPE_NODE(10)
- Node.DOCUMENT_FRAGMENT_NODE(11)
- Node.DOCUMENT_NOTATION_NODE(12) **PS:**為確保跨瀏覽器相容,最好還是講nodeType屬性與數字值進行比較。
nodeName和nodeValue屬性
對於元素節點,nodeName中儲存的始終都是元素的標籤名,而nodeValue的值則始終是null。 標籤節點的nodeValue為null,屬性節點的nodeValue為屬性值,文字節點的nodeValue為文字內容。
節點關係
- childNodes屬性:返回一個NodeList物件,是一種類陣列物件,儲存著節點的所有子節點集合。
- parentNode屬性:返回指定節點的父節點
- previousSibling屬性:返回同級的前一個節點
- nextSibling屬性:返回同級的後一個節點
- firstChild屬性:返回指定節點的子節點中的第一個
- lastChild屬性:返回指定節點的子節點中的最後一個
- **hasChildNodes()**方法:查詢該節點是否有子節點,有則true,反之false
- ownerDocument屬性:返回整個文件的文件物件
操作節點(重點)
- **appendChild()**方法:在指定節點的childNodes列表的末尾新增一個節點。 注意:如果傳入到appendChild()中的節點已經是文件的一部分,那結果就是將該節點從原來位置轉移到新位置。
- **insertBefore()**方法:在某個節點前插入。 接受兩個引數:要插入的節點和作為參照的節點。 注意:如果參照節點是null,則insertBefore()與appendChild()執行相同的操作。
- **replaceChild()**方法:將指點節點替換為新節點。 接受兩個引數:要插入的節點和要替換的節點。
- **removeChild()**方法:移除節點。 注意:替換的節點和移除的節點依舊在文件中,只是沒有自己位置了。
其他方法
- **cloneNode()**方法:用於建立呼叫這個方法的節點的一個完全相同的副本。 接受一個布林值引數:true為執行深複製,即複製節點及其整改子節點數;false為執行淺複製,即只複製節點本身。 注意:複製節點不會複製JavaScript屬性,建議在複製之前先一次節點的事件處理程式。
- **normalize()**方法:處理呼叫者的文件樹中的文字節點。移除空的文字節點,併合並相鄰的文字節點為一個文字節點。
Document型別
Document型別表示文件,在瀏覽器中document物件是一個例項,表示整個HTML頁面。nodeType為9。
文件的子節點
- documentElement屬性,該屬性始終指向HTML頁面的元素。
document.documentElement
- body屬性,直接指向元素.
document.body
- doctype屬性:獲取文件型別。(少用)
document.doctype
文件資訊
- title屬性:包含
元素中的文字,也可用於修改。
document.title
- URL屬性:包含頁面完整的URL(位址列顯示的)。
document.URL
- domain屬性:包含頁面的域名。
document.domain
- referrer屬性:儲存著連結到當前頁面的那個頁面的URL,如果沒有來源網頁則為空字串。
document.referrer
查詢元素
根據id獲取元素(掌握)
document.getElementById(“id屬性的值”)
var div = document.getElementById('main');
console.log(div);
// 獲取到的資料型別 HTMLDivElement,物件都是有型別的
// HTMLDivElement <-- HTMLElement <-- Element <-- Node <-- EventTarget
注意:由於id名具有唯一性,部分瀏覽器支援直接使用id名訪問元素,但不是標準方式,不推薦使用。
根據標籤名獲取元素(掌握)
document.getElementsByTagName(“標籤名字”),返回的是一個偽陣列。
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
var div = divs[i];
console.log(div);
}
根據name獲取元素(瞭解)
document.getElementsByName(“name屬性的值”),返回的是一個偽陣列。
var inputs = document.getElementsByName('hobby');
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
console.log(input);
}
根據類名獲取元素(瞭解)
document.getElementsByClassName(“類名”),返回的是一個偽陣列。
var mains = document.getElementsByClassName('main');
for (var i = 0; i < mains.length; i++) {
var main = mains[i];
console.log(main);
}
根據選擇器獲取元素(瞭解)
document.querySelector(“選擇器的名字”) document.querySelectorAll(“選擇器的名字”);,返回的是一個偽陣列。
var text = document.querySelector('#text');
console.log(text);
var boxes = document.querySelectorAll('.box');
for (var i = 0; i < boxes.length; i++) {
var box = boxes[i];
console.log(box);
}
特殊集合
- document.anchors 包含文件中所有帶name特性的元素。
- document.forms 包含文件中所有的元素。
- documentimages 包含文件中所有的元素。
- document.links 包含文件中所有帶href特性的元素。
文件寫入
- write()和writeln()接受一個字串引數,即要寫入到輸出流中的文字。
- open()和close()分別用於開啟和關閉網頁的輸出流。
Element型別
noteType的值為1。 可以在任何瀏覽器中通過指令碼訪問Element型別的建構函式及型別。
HTML元素(常用)
在js中設定或讀取標籤屬性:物件元素.屬性名 注意:設定或讀取某元素的樣式類,用的時className,非class。
取得特性(不常用,多隻用於自定義屬性)
元素物件.getAttribute(“屬性名”); 一般只用於取自定義特性,但需在自定義特性名前加“data-”。
設定特性(不常用,多隻用於自定義屬性)
元素物件.setAttribute(“屬性名”,“值”);
清除特性(不常用)
元素物件.removeAttribute(“屬性名”);
建立元素(常用)
**document.createElement()**可以建立新元素,接受一個引數,即要建立元素的標籤名,同時也可以包含屬性,但注意轉義“\”。
Text型別(純文字內容)
建立文字節點
**document.createTextNode()**建立新文字節點,接受一個插入節點中的文字引數。
分割文字節點(常用提取資訊)
**splitText()**將一個文字節點分成兩個文字節點,即按照指定的位置分割nodeValue值,返回一個新文字節點。接受一個位置引數。
var element = document.createElement("div");
element.className = "message";
var textNode = document.cteateTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
var newNode = element.firstChild.splitText(5);
console.log(element.firstChild.nodeValue); //"Hello"
console.log(newNode.nodeValue); //" world!"
屬性操作
非表單元素的屬性
元素物件.屬性名 href、title、id、src、className
var link = document.getElementById('link');
console.log(link.href);
console.log(link.title);
var pic = document.getElementById('pic');
console.log(pic.src);
- innerHTML和innerText 使用innerText主要設定文字的,若含有設定標籤,則標籤沒有效果。 innerHTML可設定文字內容,也可包含HTML標籤,有效果。
var box = document.getElementById('box');
box.innerHTML = '我是文字<p>我會生成為標籤</p>';
console.log(box.innerHTML);
box.innerText = '我是文字<p>我不會生成為標籤</p>';
console.log(box.innerText);
- HTML轉義符
" "
‘ '
& &
< < //less than 小於
> > // greater than 大於
空格
© ©
- innerText的相容性處理 如果這個屬性在瀏覽器中不支援,那麼這個型別是underfined。(可用於寫兼用程式碼)
function setInnerText(element, text) {
if (typeof element.textContent == "undefined") {
element.innerText = text;
} else {
element.textContent = text;
}
}
function getInnerText(element) {
if (typeof element.textContent == "undefined") {
return element.innerText;
} else {
return element.textContent;
}
}
表單元素屬性
- value 用於大部分表單元素的內容獲取(option除外)
- type 可以獲取input標籤的型別(輸入框或複選框等)
- disabled 禁用屬性
- readonly只讀屬性
- checked 複選框選中屬性
- selected 下拉選單選中屬性
樣式操作
- 使用style方式設定的樣式顯示在標籤行內 元素物件.style.屬性名
var box = document.getElementById('box');
box.style.width = '100px';
box.style.height = '100px';
box.style.backgroundColor = 'red';
- 注意 通過樣式屬性設定寬高、位置的屬性型別是字串,需要加上px。
- 凡是CSS中這個屬性是多個單詞的寫法,在js程式碼中DOM操作的時候,把-幹掉,後面的單詞的首字母大寫。
類名操作
- 修改標籤的className屬性相當於直接修改標籤的類名 元素物件.className = "樣式類名"
var box = document.getElementById('box');
box.className = 'clearfix';
建立元素的三種方式
document.write()
建立元素,如果是在頁面載入完畢後,此時通過這種方式建立元素,那麼頁面上存在的所有的內容全部被幹掉。
document.write('新設定的內容<p>標籤也可以生成</p>');
innerHTML
如果直接在body建立,效果與document.write()一樣的把頁面所有內容幹掉,如果新增某容器內就不會出現這問題
var box = document.getElementById('box');
box.innerHTML = '新內容<p>新標籤</p>';
document.createElement()
var div = document.createElement('div');
document.body.appendChild(div);
事件詳解
常用事件
方法 | 描述 |
---|---|
onclick | 滑鼠點選事件 |
onmouseover | 游標移入到某元素之上 |
onmouseout | 游標從某元素移出 |
onmousedown | 游標按鈕被按下 |
onfocus | 獲取焦點時觸發 |
onblur | 失去焦點時觸發 |
onload | 自動載入 |
onkeyup | 鍵盤彈起 |
onkeydown | 鍵盤按下 |
oninput | 當指定內容發生變化時觸發(複製貼上也觸發) |
oninvalid | 當正則表示式驗證不通過時觸發,this.setCustomValidty(“資訊”);設定預設提示資訊。 |
註冊/移除事件的三種方式(重點)
注意用什麼方式繫結事件,就用什麼方式解綁。
為同一個元素重複新增同一事件型別會覆蓋上面的方法。
- 物件.on事件型別 = 處理函式;
- 物件.on事件型別 = null; 為同一個元素繫結多個相同的事件,同類型包含覆蓋。
- 物件.addEventListener(不帶on的事件型別, 處理函式, 控制事件階段布林型別);(IE8不支援)
- 物件.attachEvent(帶on的事件型別, 處理函式);(谷歌、火狐不支援) 對應下列解綁方法,但處理函式要是對應命名函式。
- 物件.removeEventListener(不帶on的事件型別, 函式名字,控制事件階段布林型別)
- 物件.detachEvent(帶on的事件型別, 函式名字)
var box = document.getElementById('box');
box.onclick = function () {
console.log('點選後執行');
};
box.onclick = null;
box.addEventListener('click', eventCode, false);
box.removeEventListener('click', eventCode, false);
box.attachEvent('onclick', eventCode);
box.detachEvent('onclick', eventCode);
function eventCode() {
console.log('點選後執行');
}
相容程式碼
function addEventListener(element, type, fn) {
if (element.addEventListener) {
element.addEventListener(type, fn, false);
} else if (element.attachEvent){
element.attachEvent('on' + type,fn);
} else {
element['on'+type] = fn;
}
}
function removeEventListener(element, type, fn) {
if (element.removeEventListener) {
element.removeEventListener(type, fn, false);
} else if (element.detachEvent) {
element.detachEvent('on' + type, fn);
} else {
element['on'+type] = null;
}
}
事件物件
JavaScript在時間處理函式中預設傳遞了event物件,也就是事件物件。 即:
function 名字() {
}
等價於
function 名字(e) {
}
PS:為了相容,寫上e = e|| window.event;
event物件常用的屬性
屬性 | 描述 |
---|---|
type | 獲取這個事件的事件型別 |
target | 獲取繫結事件的DOM元素 |
data | 獲取事件呼叫時春如的額外引數 |
relatedTarget | 對滑鼠事件,標示觸發事件時離開或進入的DOM元素 |
currentTarget | 冒泡前的當前觸發事件的DOM物件,等同於this |
pageX/pageY | 滑鼠事件中,事件相對頁面原點的水平/垂直座標 |
result | 上一個事件處理函式返回的值 |
timeStamp | 事件發生時的時間 |
which | 獲取滑鼠的左、中、右鍵(1,2,3),或獲取鍵盤按鍵 |
eventPhase | 返回處於哪個階段 |
**event.stopPropagation();**阻止冒泡行為 **event.preventDefault();**阻止預設行為
事件的三個階段
- 捕獲階段(由外向裡)
- 當前目標階段
- 冒泡階段(由裡向外) 事件物件.eventPhase屬性可以檢視事件觸發時所處的階段 IE的事件物件是window.event;谷歌和火狐事件物件是event。
事件冒泡(注意點)
多個元素巢狀,有層次關係,這些元素都註冊了相同的事件,如果裡面的元素的事件觸發了,外面的元素的事件自動觸發。(要阻止發生)
window.event.cancelBubble = true;(谷歌、IE支援,火狐不支援)
event.stopPropagation();(谷歌、火狐支援,IE不支援)
表格物件
屬性/方法 | 描述 | |
---|---|---|
rows[] | 返回包含表格中所有行的一個數組 | |
inserRow(index) | 在表格中插入一個新行 | |
deleteRow(index) | 從表格中刪除一行 | |
cells[] | 返回包含行中所有單元格的一個數組 | |
rowIndex | 返回該行在表中的位置 | |
insertCell(index) | 在一行中的指定位置插入一個空的 | 標籤 |
deleteCell(index) | 刪除行中指定的單元格 | |
cellIndex | 返回單元格在某行單元格集合中的位置 | |
innerHtml | 設定或返回單元格的開始標籤和結束標籤之間的HTML | |
align | 設定或返回單元格內部資料的水平排列方式 | |
className | 設定或返回元素的class屬性 |
PS:表格中的rowIndex是從0開始;rows.length可查多少行
擴充套件
一次建立多節點
document物件的createDocumentFragment()建立DOM文件碎片物件,可把多個節點新增到碎片上,再一次性新增到頁面。createTextNode()。
取內部樣式表或外部樣式表中的屬性值(注意)
通過style只能獲取內聯樣式的屬性值,因此使用
-
元素.currentStyle.屬性;(只侷限於IE)
-
**document.defaultView.getComputedStyle(元素,null).屬性;**兩個引數:獲取樣式元素和偽元素。
相容程式碼
function getStyle(element,attr) {
//判斷瀏覽器是否支援這個方法
return window.getComputedStyle? window.getComputedStyle(element,null)[attr]:element.currentStyle[attr];
}
特效
偏移量(offset系列)
- offsetWidth、offsetHeight獲取寬和高
- offsetTop/Left/Right/Bottom獲取距離頂部/左部/右部/底部的距離 注意:不脫標時候與父margin+父padding+父border+自己margin;脫標後只與left…和自己的margin有關。
- offsetParent用於獲取定位的父級元素
- offsetParent和parentNode的區別
var box = document.getElementById('box');
console.log(box.offsetParent);
console.log(box.offsetLeft);
console.log(box.offsetTop);
console.log(box.offsetWidth);
console.log(box.offsetHeight);
頁面事件(scroll系列)(重點)
- scrollWidth、scrollHeight內容實際寬、高,不包含邊框。
- scrollLeft、scrollTop設定或獲取位於物件左邊界/最頂端和視窗中可見內容的最頂端之間的距離。
相容程式碼
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
客戶區大小(client系列)可視區域
- clientWidth、clientHeight元素可視區域的寬、高(不包含邊框)。
- clientLeft/Top左邊框/上邊框的寬度。
- clientX、clientY可視區域滑鼠的x、y座標。
附
pageX相對左部頁面邊界的x座標。(IE8不支援) pageY相對頂部頁面邊界的Y座標。