一涩馆、DOM簡介
文檔對象模型(Document Object Model罐栈,簡稱 DOM)优床,是 W3C 組織推薦的處理可擴展標記語言(HTML或者XML)的標準編程接口。
W3C 已經(jīng)定義了一系列的 DOM 接口丁鹉,通過這些 DOM 接口可以改變網(wǎng)頁的內(nèi)容、結構和樣式悴能。
- 文檔:一個頁面就是一個文檔揣钦,DOM 中使用 document 表示
- 元素:頁面中的所有標簽都是元素,DOM 中使用 element 表示
- 節(jié)點:網(wǎng)頁中的所有內(nèi)容都是節(jié)點(標簽漠酿、屬性冯凹、文本、注釋等)炒嘲,DOM 中使用 node 表示
DOM 把以上內(nèi)容都看做是對象宇姚。
二、獲取元素
1. 根據(jù) ID 獲取
使用 getElementById() 方法可以獲取帶有 ID 的元素對象夫凸。
document.getElementById('id');
2. 根據(jù)標簽名獲取
使用 getElementsByTagName() 方法可以返回帶有指定標簽名的對象的集合浑劳。
document.getElementsByTagName('標簽名');
注意:
因為得到的是一個對象的集合,所以我們想要操作里面的元素就需要遍歷夭拌。
得到元素對象是動態(tài)的
如果獲取不到元素,則返回為空的偽數(shù)組(因為獲取不到對象)
還可以獲取某個元素(父元素)內(nèi)部所有指定標簽名的子元素.
element.getElementsByTagName('標簽名');
注意:父元素必須是單個對象(必須指明是哪一個元素對象). 獲取的時候不包括父元素自己魔熏。
3. 通過 HTML5 新增的方法獲取
根據(jù)類名返回元素對象集合
document.getElementsByClassName('類名');
根據(jù)指定選擇器返回第一個元素對象
document.querySelector('選擇器');
根據(jù)指定選擇器返回
document.querySelectorAll('選擇器');
注意:
querySelector 和 querySelectorAll里面的選擇器需要加符號,
比如:document.querySelector('#nav');
4. 獲取特殊元素(body,html)
返回body元素對象
doucument.body
返回html元素對象
document.documentElement
三啼止、操作元素
1. 改變元素內(nèi)容
element.innerText
從起始位置到終止位置的內(nèi)容, 但它去除 html 標簽道逗, 同時空格和換行也會去掉
element.innerHTML
起始位置到終止位置的全部內(nèi)容,包括 html 標簽献烦,同時保留空格和換行
2. 常用元素的屬性操作
- innerText滓窍、innerHTML 改變元素內(nèi)容
- src、href
- id巩那、alt吏夯、title
3. 表單元素的屬性操作
利用 DOM 可以操作如下表單元素的屬性:
type、value即横、checked噪生、selected、disabled
4. 樣式屬性操作
我們可以通過 JS 修改元素的大小东囚、顏色跺嗽、位置等樣式。
- element.style 行內(nèi)樣式操作
- element.className 類名樣式操作
注意:
- JS 里面的樣式采取駝峰命名法 比如 fontSize、 backgroundColor
- JS 修改 style 樣式操作桨嫁,產(chǎn)生的是行內(nèi)樣式植兰,CSS 權重比較高
- 如果樣式修改較多,可以采取操作類名方式更改元素樣式
- class因為是個保留字璃吧,因此使用className來操作元素類名屬性
- className 會直接更改元素的類名楣导,會覆蓋原先的類名
5. classList 屬性
classList屬性是HTML5新增的一個屬性,返回元素的類名畜挨。但是ie10以上版本支持筒繁。
該屬性用于在元素中添加,移除及切換 CSS 類巴元。
添加類:
element.classList.add(’類名’);
focus.classList.add(‘current’);
移除類:
element.classList.remove(’類名’);
focus.classList.remove(‘current’);
切換類:
element.classList.toggle(’類名’);
focus.classList.toggle(‘current’);
注意以上方法里面毡咏,所有類名都不帶點
6. 排他思想
如果有同一組元素,我們想要某一個元素實現(xiàn)某種樣式务冕, 需要用到循環(huán)的排他思想算法:
- 所有元素全部清除樣式(干掉其他人)
- 給當前元素設置樣式 (留下我自己)
- 注意順序不能顛倒血当,首先干掉其他人,再設置自己
7. 自定義屬性的操作
- 獲取屬性值
element.屬性 獲取屬性值禀忆。
element.getAttribute('屬性');
區(qū)別:
element.屬性 獲取內(nèi)置屬性值(元素本身自帶的屬性)
element.getAttribute(‘屬性’); 主要獲得自定義的屬性 (標準) 我們程序員自定義的屬性 - 設置屬性值
element.屬性 = ‘值’ 設置內(nèi)置屬性值臊旭。
element.setAttribute('屬性', '值');
區(qū)別:
element.屬性 設置內(nèi)置屬性值
element.setAttribute(‘屬性’); 主要設置自定義的屬性 (標準) - 移除屬性
element.removeAttribute('屬性');
8. H5自定義屬性
自定義屬性目的:是為了保存并使用數(shù)據(jù)。有些數(shù)據(jù)可以保存到頁面中而不用保存到數(shù)據(jù)庫中箩退。
自定義屬性獲取是通過getAttribute('屬性') 獲取离熏。
但是有些自定義屬性很容易引起歧義,不容易判斷是元素的內(nèi)置屬性還是自定義屬性戴涝。
H5給我們新增了自定義屬性:
- 設置H5自定義屬性
H5規(guī)定自定義屬性data-開頭做為屬性名并且賦值滋戳。
比如 <div data-index=“1”></div>
或者使用 JS 設置
element.setAttribute(‘data-index’, 2) - 獲取H5自定義屬性
兼容性獲取 element.getAttribute('data-index');
H5新增 element.dataset.index 或者 element.dataset[‘index’] ie 11才開始支持
四、節(jié)點操作
1. 獲取元素通常使用兩種方式
- 利用 DOM 提供的方法獲取元素
document.getElementById()
document.getElementsByTagName()
document.querySelector 等
邏輯性不強啥刻、繁瑣 - 利用節(jié)點層級關系獲取元素
利用父子兄節(jié)點關系獲取元素
邏輯性強奸鸯, 但是兼容性稍差
2. 節(jié)點概述
網(wǎng)頁中的所有內(nèi)容都是節(jié)點(標簽、屬性可帽、文本娄涩、注釋等),在DOM 中映跟,節(jié)點使用 node 來表示蓄拣。
HTML DOM 樹中的所有節(jié)點均可通過 JavaScript 進行訪問,所有 HTML 元素(節(jié)點)均可被修改努隙,也可以創(chuàng)建或刪除球恤。
一般地,節(jié)點至少擁有nodeType(節(jié)點類型)荸镊、nodeName(節(jié)點名稱)和nodeValue(節(jié)點值)這三個基本屬性咽斧。
元素節(jié)點 nodeType 為 1
屬性節(jié)點 nodeType 為 2
文本節(jié)點 nodeType 為 3 (文本節(jié)點包含文字堪置、空格、換行等)
注釋節(jié)點 nodeType 為 8
我們在實際開發(fā)中张惹,節(jié)點操作主要操作的是元素節(jié)點
3. 節(jié)點層級
利用 DOM 樹可以把節(jié)點劃分為不同的層級關系晋柱,常見的是父子兄層級關系。
- 父級節(jié)點
node.parentNode
parentNode 屬性可返回某節(jié)點的父節(jié)點诵叁,注意是最近的一個父節(jié)點
如果指定的節(jié)點沒有父節(jié)點則返回 null
- 子節(jié)點
①parentNode.childNodes
(標準)
parentNode.childNodes 返回包含指定節(jié)點的子節(jié)點的集合,該集合為即時更新的集合钦椭。
注意:返回值里面包含了所有的子節(jié)點拧额,包括元素節(jié)點,文本節(jié)點等彪腔。
如果只想要獲得里面的元素節(jié)點侥锦,則需要專門處理。 所以我們一般不提倡使用childNodes
var ul = document. querySelector('ul');
for(var i = 0; i < ul.childNodes.length;i++) {
if (ul.childNodes[i].nodeType == 1) { // ul.childNodes[i] 是元素節(jié)點
console.log(ul.childNodes[i]);
}
}
②parentNode.children
(非標準)
parentNode.children 是一個只讀屬性德挣,返回所有的子元素節(jié)點恭垦。它只返回子元素節(jié)點,其余節(jié)點不返回格嗅。
雖然children 是一個非標準番挺,但是得到了各個瀏覽器的支持,因此我們可以放心使用
③parentNode.firstChild
firstChild 返回第一個子節(jié)點屯掖,找不到則返回null玄柏。同樣,也是包含所有的節(jié)點贴铜。包括元素節(jié)點粪摘,文本節(jié)點等。
④parentNode.lastChild
lastChild 返回最后一個子節(jié)點绍坝,找不到則返回null徘意。同樣,也是包含所有的節(jié)點轩褐。包括元素節(jié)點椎咧,文本節(jié)點等。
⑤parentNode.firstElementChild
firstElementChild 返回第一個子元素節(jié)點灾挨,找不到則返回null邑退。
⑥parentNode.lastElementChild
lastElementChild 返回最后一個子元素節(jié)點,找不到則返回null劳澄。
注意:這兩個方法有兼容性問題地技,IE9 以上才支持。
實際開發(fā)中秒拔,firstChild 和 lastChild 包含其他節(jié)點莫矗,操作不方便,而 firstElementChild 和 lastElementChild 又有兼容性問題,
那么我們?nèi)绾潍@取第一個子元素節(jié)點或最后一個子元素節(jié)點呢作谚?
解決方案:
如果想要第一個子元素節(jié)點三娩,可以使用 parentNode.chilren[0]
如果想要最后一個子元素節(jié)點,可以使用 parentNode.chilren[parentNode.chilren.length - 1]
- 兄弟節(jié)點
node.nextSibling
nextSibling 返回當前元素的下一個兄弟元素節(jié)點妹懒,找不到則返回null雀监。同樣,也是包含所有的節(jié)點眨唬。
node.previousSibling
previousSibling 返回當前元素上一個兄弟元素節(jié)點会前,找不到則返回null。同樣匾竿,也是包含所有的節(jié)點瓦宜。
node.nextElementSibling
nextElementSibling 返回當前元素下一個兄弟元素節(jié)點,找不到則返回null岭妖。
node.previousElementSibling
previousElementSibling 返回當前元素上一個兄弟節(jié)點临庇,找不到則返回null。
注意:這兩個方法有兼容性問題昵慌, IE9 以上才支持假夺。
自己封裝一個兼容性的函數(shù):
function getNextElementSibling(element) {
var el = element;
while (el = el.nextSibling) {
if (el.nodeType === 1) {
return el;
}
}
return null;
}
4. 節(jié)點創(chuàng)建
document.createElement('tagName')
document.createElement() 方法創(chuàng)建由 tagName 指定的 HTML 元素。因為這些元素原先不存在斋攀,是根據(jù)我們的需求動態(tài)生成的侄泽,所以我們也稱為動態(tài)創(chuàng)建元素節(jié)點。
5. 節(jié)點添加
node.appendChild(child)
node.appendChild() 方法將一個節(jié)點添加到指定父節(jié)點的子節(jié)點列表末尾蜻韭。類似于 CSS 里面的 after 偽元素悼尾。
node.insertBefore(child, 指定元素)
node.insertBefore() 方法將一個節(jié)點添加到父節(jié)點的指定子節(jié)點前面。類似于 CSS 里面的 before 偽元素肖方。
6. 節(jié)點刪除
node.removeChild(child)
node.removeChild() 方法從 DOM 中刪除一個子節(jié)點闺魏,返回刪除的節(jié)點。
阻止鏈接跳轉需要添加 javascript:void(0); 或者 javascript:;
<a href='javascript:;'>刪除</a>
俯画?析桥??什么都不寫也可以啊艰垂,留一個疑問泡仗??猜憎?
2020年2月1日疑問解除:
如果什么都不寫娩怎,a標簽作為一個按鈕進行事件響應時,可能不會響應完全胰柑,切割輪播圖的坑截亦。
<a href="javascript:;" class="next">></a>
<script src="js/jquery.min.js"></script>
<script>
$(function () {
var index = 0;
var flag = true;
$(".next").on("click", function () {
if (flag == true) {
flag = false;
index--;
$("li").each(function (key) {
$(this).css({
"transform": "rotateX(" + (index * 90) + "deg)",
"transition-delay": (key * 0.2) + "s"
});
});
setTimeout(function () {
flag = true;
}, 1000);
}
});
});
</script>
完整代碼見代碼附錄爬泥。
7. 節(jié)點復制(節(jié)點克隆)
node.cloneNode()
node.cloneNode() 方法返回調(diào)用該方法的節(jié)點的一個副本崩瓤。 也稱為克隆節(jié)點/拷貝節(jié)點
注意:
- 如果括號參數(shù)為空或者為 false 袍啡,則是淺拷貝,即只克隆復制節(jié)點本身却桶,不克隆里面的子節(jié)點境输。
- 如果括號參數(shù)為 true ,則是深度拷貝颖系,會復制節(jié)點本身以及里面所有的子節(jié)點畴嘶。
8. 三種動態(tài)創(chuàng)建元素區(qū)別
document.write()
element.innerHTML
document.createElement()
區(qū)別:
- document.write 是直接將內(nèi)容寫入頁面的內(nèi)容流,但是文檔流執(zhí)行完畢集晚,則它會導致頁面全部重繪
- innerHTML 是將內(nèi)容寫入某個 DOM 節(jié)點,不會導致頁面全部重繪
- innerHTML 創(chuàng)建多個元素效率更高(不要拼接字符串区匣,采取數(shù)組形式拼接)偷拔,結構稍微復雜
- createElement() 創(chuàng)建多個元素效率稍低一點點,但是結構更清晰
總結:不同瀏覽器下亏钩,innerHTML 效率要比 creatElement 高
五莲绰、DOM 總結
關于dom操作,主要針對于元素對象的操作姑丑。
主要有創(chuàng)建蛤签、增、刪栅哀、改震肮、查、屬性操作留拾。
1. 創(chuàng)建
- document.write
- innerHTML
- createElement
2. 增
- appendChild
- insertBefore
3. 刪
- removeChild
4. 改
主要修改dom的元素屬性戳晌,dom元素的內(nèi)容、屬性, 表單的值等
- 修改元素屬性: src痴柔、href沦偎、title等
- 修改普通元素內(nèi)容: innerHTML 、innerText
- 修改表單元素: value咳蔚、type豪嚎、disabled等
- 修改元素樣式: style、className
5. 查
主要獲取查詢dom的元素
- DOM提供的API 方法: getElementById谈火、getElementsByTagName 古老用法 不太推薦
- H5提供的新方法: querySelector侈询、querySelectorAll 提倡
- 利用節(jié)點操作獲取元素: 父(parentNode)、子(children)糯耍、兄(previousElementSibling妄荔、nextElementSibling) 提倡
6. 屬性操作
主要針對于自定義屬性
- setAttribute:設置dom的屬性值
- getAttribute:得到dom的屬性值
- removeAttribute移除屬性
代碼附錄:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>切割輪播圖</title>
<style>
* {
padding: 0;
margin: 0;
}
body {
background-color: #000000;
}
.view {
width: 560px;
height: 300px;
margin: 100px auto;
position: relative;
}
ul {
width: 100%;
height: 100%;
list-style: none;
transform: rotate3d(0, 0, 0, 0deg);
transform-style: preserve-3d;
}
ul > li {
width: 20%;
height: 100%;
float: left;
position: relative;
transform-style: preserve-3d;
transition: transform 0.5s;
}
ul > li > span {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
ul > li > span:nth-of-type(1) {
background: url("images/q1.jpg");
transform: translateZ(150px);
}
ul > li > span:nth-of-type(2) {
background: url("images/q2.jpg");
transform: translateY(-150px) rotateX(90deg);
}
ul > li > span:nth-of-type(3) {
background: url("images/q3.jpg");
transform: translateZ(-150px) rotateX(180deg);
}
ul > li > span:nth-of-type(4) {
background: url("images/q4.jpg");
transform: translateY(150px) rotateX(-90deg);
}
ul > li:nth-of-type(2) > span {
background-position: -100% 0;
}
ul > li:nth-of-type(3) > span {
background-position: -200% 0;
}
ul > li:nth-of-type(4) > span {
background-position: -300% 0;
}
ul > li:nth-of-type(5) > span {
background-position: -400% 0;
}
.pre, .next {
width: 60px;
height: 60px;
text-align: center;
line-height: 60px;
position: absolute;
top: 50%;
text-decoration: none;
font-size: 40px;
transform: translate(0, -50%);
background-color: rgba(0, 0, 0, 0.5);
color: white;
}
.pre {
left: 0;
}
.next {
right: 0;
}
</style>
</head>
<body>
<div class="view">
<ul>
<li>
<span></span>
<span></span>
<span></span>
<span></span>
</li>
<li>
<span></span>
<span></span>
<span></span>
<span></span>
</li>
<li>
<span></span>
<span></span>
<span></span>
<span></span>
</li>
<li>
<span></span>
<span></span>
<span></span>
<span></span>
</li>
<li>
<span></span>
<span></span>
<span></span>
<span></span>
</li>
</ul>
<a href="javascript:;" class="pre"><</a>
<a href="javascript:;" class="next">></a>
</div>
<script src="js/jquery.min.js"></script>
<script>
$(function () {
var index = 0;
var flag = true;
$(".next").on("click", function () {
if (flag == true) {
flag = false;
index--;
$("li").each(function (key) {
$(this).css({
"transform": "rotateX(" + (index * 90) + "deg)",
"transition-delay": (key * 0.2) + "s"
});
});
setTimeout(function () {
flag = true;
}, 1000);
}
});
$(".pre").on("click", function () {
if (flag == true) {
flag = false;
index++;
$("li").each(function (key) {
$(this).css({
"transform": "rotateX(" + index * 90 + "deg",
"transition-delay": key * 0.2 + "s"
});
});
setTimeout(function () {
flag = true;
}, 1000);
}
});
});
</script>
</body>
</html>