1. 程式人生 > >DOM,BOM

DOM,BOM

des lock ack host 鍵盤 文件夾 ram 選擇 ins

1. DOM

1.1. DOM基本概念

1.1.2. 什麽是DOM?

Document Object Model:文檔對象模型,也叫文檔樹模型,是一套操作HTML和XML的一套API

1. 文檔對象模型
HTML頁面的所有的內容,包括標簽、節點、註釋、屬性等,在JS的DOM中,都存在一個一個的對象與之對應。因此當我們想要操作這些HTML的內容時,只需要操作這些對象即可。

節點:頁面中所有的內容,包括標簽、節點、註釋、樹形都被封裝成了對象,我們把這些對象叫做節點。
元素:我們最常操作的是標簽節點,也叫元素。


2. 文檔樹模型
HTML結構是一個樹形結構,同樣的,這些對應的對象也是一個樹形的結構,樹形結構的好處是能夠非常容易找到某個節點的子節點、父節點、兄弟節點。
子節點:child
兄弟節點:sibling
父節點:parent

3. API:Application Programming Interface:應用程序編程接口,其實就是一大堆的方法,我們可以把API看成是工具。做不同的事情需要不同的工具。
做飯需要一套做飯的工具:鍋碗瓢盆
打仗需要一套打仗的工具:刀槍劍戟
找對象需一套找對象的工具:錢權顏緣 +  車房錢權
DOM:
用來操作頁面元素的一套工具。 BOM:用來操作瀏覽器一些行為的一套工具。 4. XML:XML(Extensible Markup Language:可擴展性標記語言,通常用於配置文件,或者和json一樣用於數據交互。 <student> <name>張三</name> <age>18</age> <sex>男</sex> </student>

樹形結構示意圖:

技術分享圖片

1.2. DOM初體驗

想要操作DOM,首先需要獲取到DOM對象。

【案例:DOM對象初體驗.html】

1.2.1. 根據id獲取元素

<div id="box">123</div>
var element = document.getElementById("box");

1. document:指的是整個html頁面,在DOM中被封裝成了一個對象,就是document對象
2. getElementById:通過id獲取元素
3. 參數是一個字符串,即id
4. 返回值是一個元素,即一個對象,標簽中存在的屬性,在這個元素中也有屬性與之一一對應。

1.2.2. 如何打印一個對象

console.log():以標簽的形式打印一個對象
console.dir():以對象的形式打印一個對象

1.3. 註冊事件

JavaScript和HTML之間的交互是通過事件來實現的。 事件就是文檔或者瀏覽器窗口發生的一些特定的交互瞬間。 JavaScript是一門事件驅動的腳本語言

1.3.1. 事件三要素

事件源:觸發事件的元素
事件名稱:觸發的事件名稱
事件處理函數:觸發事件時調用的函數

1.3.2. 註冊事件的兩種方式

  • 行內式註冊事件(不用)
<img src="images/1.jpg" alt="描述" id="img" onclick="changePic()">
  • 內嵌式註冊事件
var img = document.getElementById("img");/*找到img這個標簽*/
img.onclick = function() {
  img.src = "images/2.gif";
}

1.3.3. 給a標簽註冊事件

return false可以阻止頁面跳轉。

1.4. 查找DOM對象

1.4.1. 根據標簽名獲取元素

var links = document.getElementsByTagName(“a”)
//1. 根據標簽名獲取元素,返回的是一個偽數組
//2. 偽數組:可以跟數組一樣進行遍歷,但是不能使用數組的方法。
//3. this的使用,誰調用,指向誰
對於getElementsByTagName方法,不僅可以通過document調用,還可以通過元素來調用
1. document.getElementsByTagName("a");//查找頁面中所有的a標簽。
2. var box = document.getElementById("box");
    box.getElementsByTagName("a");//查找box中所有的a標簽。

1. 屬性操作

1.1. 普通標簽屬性

我們知道,在標簽中存在的屬性,在DOM對象中同樣存在著對應的屬性,只要修改了標簽的屬性或者DOM對象的屬性,兩邊都會變化。常見的屬性有:src、title、src、href、className、id等

鼠標經過事件與鼠標離開事件

onmouseover:當鼠標經過時觸發
onmouseout:當鼠標離開時觸發

1.2. 表單屬性操作

常見的表單屬性有:disabled、type、value、checked、selected

1.2.1. 布爾類型屬性

對於disabled、checked、selected三個屬性來說,比較特殊。

在標簽中,只要指定了disabled屬性,無論有值沒值,都代表這個input是被禁用的。
在DOM對象中,disabled的屬性是一個布爾類型的屬性,值只有true或者false

獲得焦點與失去焦點案例

onfocus:獲得焦點時觸發
onblur:失去焦點時觸發

1.3. 標簽的自定義屬性

我們之前討論的屬性,都是HTML規範中,標簽本來就有的屬性,對於標簽自定義的一些屬性,比較特殊。

在html頁面中,定義一個自定義屬性

<div id="box" aa="bb"></div>

在對應的DOM對象中是不存在的,在DOM對象中只會存在固定的那些屬性。

var box = document.getElementById("box");
console.log(box.aa);//undefined

1.3.1. attribute系列

attribute系列方法用於設置標簽的屬性,不管是自定義的還是固有的屬性。

getAttribute(name);
setAttribute(name, value);
removeAttribute(name);

1.3.2. 排他思想

幹掉所有人,復活我自己

1.4在原來的類名基礎上 添加/刪除類名( IE678不兼容)

btn.onclick = function () { box.classList.add("red"); } btn1.onclick = function () { 刪除red類 box.classList.remove("red"); }

1. 克隆節點

語法:var newNode = node.cloneNode(deep)

功能:在內存中克隆一份節點

返回值:克隆出來的節點

參數:deep

  • false:默認值:是淺復制,只會復制標簽,節點本身,不會復制節點的孩子。
  • true:深度復制,會復制標簽,還會復制標簽的所有內容 常用
  1. 克隆出來的節點跟原來的節點沒有關系了,修改了也不會相互影響。
  2. 如果克隆的節點帶了id,我們需要給id重新設置一個值,不讓id沖突

2. 添加節點

2.1. appendChild

語法:parent.appendChild(newChild)

parent:調用者,父節點來調用

newChild:需要添加的那個孩子。

作用:把newChild添加到parent的孩子的最後面。

如果添加的是頁面中本來就存在的元素,是一個剪切的效果,原來的就不在了。

var demo = document.getElementById("demo");
var box = document.getElementById("box");
box.appendChild(demo);

2.2. insertBefore

語法:parent.insertBefore(newChild, refChild);

parent:必須要父節點來調用

newChild:需要添加的那個節點

refChild:添加到哪一個節點的前面。

var ul = document.getElementById("list");
var li = document.createElement("li");
li.innerHTML = "驥驥";
//就是添加到子節點的最前面。
ul.insertBefore(li, ul.children[0]);

2.3. 雙擊事件

ondblclick:雙擊的時候觸發

3. 創建節點

3.1. document.write(基本不用)

可以生成新的節點,但是不推薦使用。如果頁面已經加載完成了,你還是用document.write寫內容的話,會把之前的頁面給覆蓋掉

原理:頁面從上往下加載的時候,會開啟一個文檔流,當頁面加載完,文檔流就會關閉。

document.write的本意就是在文檔流上寫入內容。如果頁面沒加載完成,文檔流還是開著的,document.write直接在這個文檔流上寫東西

如果頁面加載完成了,還是用document.write寫東西,會重新開啟一個新的文檔流,往新的文檔流上寫東西,舊的文檔流就被新的文檔流覆蓋了。

3.2. innerHTML

innerHTML也可以創建節點

innerHTML創建節點的時候有一個特點,如果原來有內容的話,使用innerHTML會把原先的內容給幹掉。

慎用:很容易出現效率問題。

3.3. createElement

語法:var element = document.createElement("tagName");

作用:在內存裏面創建了一個節點

返回:一個元素

用途非常的廣泛。

4. 刪除節點

語法:parent.removeChild(child);

功能:有父盒子調用,刪除裏面的一個子元素。

刪除節點必須要父節點

1. 標簽內容

innerText和innerHTML屬性都是用來獲取和設置標簽的內容的。但是二者還是有區別的。

1.1. innerHTML

innerHTML可以用於獲取和設置標簽的所有內容,包括標簽和文本內容

//innerHTML:內部的HTML
//  獲取標簽內容的時候,不管標簽還是文本,都能獲取到   標簽+文本
//  innerHTML設置內容的時候,覆蓋原來內容,標簽也能生效,瀏覽器能解析這個標簽。

1.2. innerText

innerText可以用於獲取和設置標簽的文本內容,會丟棄掉標簽

//innerText:內部 文本
//  獲取標簽內容的時候,只會獲取文本,標簽扔掉了
//  設置標簽內容的時候,覆蓋原來內容,對標簽進行轉義(目的:把標簽直接當文本來用)

二者的區別:

  • innerHTML是W3C的標準屬性,而innerText是IE提出來的屬性,存在兼容性問題。因此更加推薦大家使用innerHTML。
  • innerText的作用:防止xss攻擊

1.3. innerText的兼容性問題

瀏覽器兼容性:指網頁在各種瀏覽器上的顯示效果不一致。或者是一些屬性和方法在低版本的瀏覽器中不支持。

//1. innerText是IE提出來的屬性,因此低版本的火狐瀏覽器不支持這個屬性。
//2. 火狐有一個textContent屬性,效果跟innerText一樣,但是IE678不支持這個屬性

解決瀏覽器兼容性的處理方式:

1. 能力檢測(常用)
2. 代理檢測
3. 怪癖檢測

書寫innerText的兼容性代碼

//獲取標簽的innerText(兼容所有瀏覽器)
function getInnerText(element) {
    if (typeof element.innerText === "string") {
        return element.innerText;
    } else {
        return element.textContent;
    }
}

//設置標簽的innerText(兼容所有瀏覽器)
function setInnerText(element, value) {
    //能力檢測
    if (typeof element.innerText === "string") {
        element.innerText = value;
    } else {
        element.textContent = value;
    }
}

2. 節點操作

2.1. 節點的屬性

節點分類:

元素節點、文本節點、屬性節點、註釋節點

節點常用的屬性

nodeType: 節點類型:元素節點的nodeType = 1

nodeName: 節點名稱

nodeValue: 節點值

// // 標簽節點 屬性節點 註釋節點 文本節點 // //nodeType 1 2 8 3

2.2. 節點層次

2.2.1. 孩子節點

//childNodes:獲取所有的孩子節點(包括了元素節點和其他很多類型的節點,基本不常用)
//children:獲取所有的子元素(用途很廣泛)
//firstChild //第一個節點
//firstElementChild //第一個子元素 有兼容性問題 可以封裝一個兼容性方法
children[0];
//lastChild //最後一個節點
//lastElementChild //最後一個子元素 有兼容性問題 可以封裝一個兼容性方法
children[children.length-1]

2.2.2. 兄弟節點

//1. nextSibling:下一個兄弟節點
//2. nextElementSibling:下一個兄弟元素(IE678不兼容)
//3. previousSibling//上一個兄弟節點
//4. previousElementSibling //上一個兄弟元素 有兼容性問題 可以封裝一個兼容性方法

2.2.3. 父節點

//1. parentNode:父節點  沒有兼容性問題

3. 樣式操作