1. 程式人生 > >JavaScript DOM筆記

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轉義符
"		&quot;
‘		&apos;
&		&amp;
<		&lt;    //less than  小於
>		&gt;   // greater than  大於
空格	   &nbsp;
©		&copy;
  • 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();**阻止預設行為

事件的三個階段

  1. 捕獲階段(由外向裡)
  2. 當前目標階段
  3. 冒泡階段(由裡向外) 事件物件.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座標。