DOM
概念
所謂DOM,其實(shí)就是 Document Object Model文檔對象模型,毫無疑問,這個(gè)東西是讓我們?nèi)ゲ僮鲗ο蟮?,那什么是對象呢?其?shí)就是文檔的對象。,在文檔中一切皆為對象,比如html,body, p,div等等這些都是文檔的對象。通過操作這些對象我們可以對這些文檔對象進(jìn)行有趣的操作,比如點(diǎn)擊div然后div隨機(jī)變換背景色。
解析過程
HTML加載完成,渲染引擎會在內(nèi)存中把html生成一個(gè)DOM樹,我們可以通過js的選擇節(jié)點(diǎn)操作去獲取DOM上的元素節(jié)點(diǎn),然后就可以對這個(gè)元素進(jìn)行一系列的操作,最后又會被渲染樹渲染后頁面中。
DOM樹一切皆為節(jié)點(diǎn)
UTOOLS1583583474567.png
在上圖HTML中就可以顯示出一切皆為節(jié)點(diǎn)
- 元素節(jié)點(diǎn):HTML標(biāo)簽
- 屬性節(jié)點(diǎn):標(biāo)簽的屬性
- 文本節(jié)點(diǎn):標(biāo)簽中的文字
DOM可以做什么?
- 找對象(元素節(jié)點(diǎn))
- 設(shè)置元素屬性值
- 設(shè)置元素樣式
- 動態(tài)創(chuàng)建和刪除元素
- 事件的觸發(fā)響應(yīng):事件源、事件、事件的驅(qū)動
獲取DOM結(jié)構(gòu)
- 獲取文檔對象:document
- 獲取html:document.documentElement
- 獲取body: document.body
獲取其他的DOM節(jié)點(diǎn)
// id選擇器
var box = document.getElementById("box");
// 類選擇器
var box = document.getElementsByClassName("box");
// 標(biāo)簽選擇器
var box = document.getElementsByTagName("div");
// css通用選擇器
var box = document.querySelector(".box");
事件
事件三要素
- 事件源(引起事件的標(biāo)簽)
- 事件(js已定義好的事件)
- 事件驅(qū)動程序(對節(jié)點(diǎn)的操作)
常用的事件如下:
UTOOLS1583585296518.png
綁定事件的方式
直接綁定匿名函數(shù)
// id選擇器
var box = document.getElementById("box");
box.onclick = function(){
alert("我觸發(fā)了點(diǎn)擊事件");
}
先單獨(dú)定義函數(shù),在綁定
var box = document.getElementById("box");
box.onclick = click();
function click() {
alert("我觸發(fā)了點(diǎn)擊事件");
}
行內(nèi)綁定(不推薦)
<div id="box" class="box" onclick="click();"></div>
<script>
function click() {
alert("我觸發(fā)了點(diǎn)擊事件");
}
</script>
JavaScript入口函數(shù) window.onload()
此函數(shù)調(diào)用,是當(dāng)頁面加載完畢(文檔圖片),觸發(fā)onload函數(shù)
<script type="text/javascript">
window.onload = function () {
console.log("alex"); //等頁面加載完畢時(shí),打印字符串
}
</script>
樣式屬性操作
<div id="box" class="box" onclick="click();"></div>
<script>
var box = document.getElementById("box");
box.onclick = function(){
// 設(shè)置盒子的背景顏色
this.style.backgroundColor = "blue";
}
</script>
值得操作
值得操作又分為雙標(biāo)簽和單標(biāo)簽
- 雙標(biāo)簽 我們可以使用
innerHTML和innerText - 單標(biāo)簽 只能使用value獲取值和設(shè)置值
<div id='box'></div>
<input type='text' value = 'alex' id='user'>
<script>
window.onload = function(){
//1.獲取事件源(事件對象,在文檔中一切的標(biāo)簽都是對象)
var oDiv = docuement.getElementById('box');
var oInput = docuement.getElementById('user');
//2.事件
oDiv.onclick = function(){
//3.事件驅(qū)動程序
oDiv.innerText = 'alex';//僅僅設(shè)置文本內(nèi)容
oDiv.innerHTML = '<h1>alex</h1>';//將標(biāo)簽和文本內(nèi)容一起解析
};
//2.事件
oInput.onclick = function(){
//3.事件驅(qū)動程序 只有有value屬性的 才能使用value賦值和設(shè)置值
oInput.value = 'hhhh';
}
};
</script>
標(biāo)簽屬性操作
<script>
//window.onload頁面加載完畢以后再執(zhí)行此代碼
window.onload = function () {
//需求:鼠標(biāo)放到img上,更換為另一張圖片,也就是修改路徑(src的值)。
//步驟:
//1.獲取事件源
//2.綁定事件
//3.書寫事件驅(qū)動程序
//1.獲取事件源
var oImg = document.getElementById("box");
//2.綁定事件(懸停事件:鼠標(biāo)進(jìn)入到事件源中立即出發(fā)事件)
oImg.onmouseover = function () {
//3.書寫事件驅(qū)動程序(修改src)
img.src = "image/jd2.png";
// this.src = "image/jd2.png";
}
//2.綁定事件(懸停事件:鼠標(biāo)進(jìn)入到事件源中立即出發(fā)事件)
oImg.onmouseout = function () {
//3.書寫事件驅(qū)動程序(修改src)
img.src = "image/jd1.png";
}
}
</script>
節(jié)點(diǎn)操作
創(chuàng)建節(jié)點(diǎn)
新的標(biāo)簽(元素節(jié)點(diǎn)) = document.createElement("標(biāo)簽名");
<script type="text/javascript">
var a1 = document.createElement("li"); //創(chuàng)建一個(gè)li標(biāo)簽
var a2 = document.createElement("adbc"); //創(chuàng)建一個(gè)不存在的標(biāo)簽
console.log(a1);
console.log(a2);
console.log(typeof a1);
console.log(typeof a2);
</script>
UTOOLS1583586910616.png
插入節(jié)點(diǎn)
父節(jié)點(diǎn).appendChild(新的子節(jié)點(diǎn));
<div id="parent">
<div id="child">我是兒子</div>
</div>
<script>
var parent = document.getElementById("parent");
var ele = document.createElement("p");
ele.innerHTML = "我是追加元素"
// 會在父元素內(nèi)的某位添加一個(gè)節(jié)點(diǎn)
parent.appendChild(ele);
</script>
UTOOLS1583588479234.png
父節(jié)點(diǎn).insertBefore(新的子節(jié)點(diǎn),參考節(jié)點(diǎn));
<div id="parent">
<div id="child">我是兒子</div>
</div>
<script>
var parent = document.getElementById("parent");
var ele = document.createElement("p");
var child = document.getElementById("child");
ele.innerHTML = "我是追加元素"
//會在父節(jié)點(diǎn)下的以一個(gè)節(jié)點(diǎn)為參考,添加到這個(gè)參考元素的前面
parent.insertBefore(ele, child);
</script>
image-20200307214342443.png
刪除節(jié)點(diǎn)
父節(jié)點(diǎn).removeChild(子節(jié)點(diǎn));
<div id="parent">
<div id="child">我是兒子</div>
</div>
<script>
var parent = document.getElementById("parent");
var ele = document.createElement("p");
var child = document.getElementById("child");
// 刪除子節(jié)點(diǎn)
parent.removeChild(child);
</script>
image-20200307214644712.png
兄弟節(jié)點(diǎn)
- 節(jié)點(diǎn).nextSibling
- 節(jié)點(diǎn).previousSibling
- 節(jié)點(diǎn).nextElementSibling
- 節(jié)點(diǎn).previousElementSibling
<div id="parent">
<div>我是前兄弟</div>
<div id="child">我是兒子</div>
<div>我是后兄弟</div>
</div>
<script>
var parent = document.getElementById("parent");
var ele = document.createElement("p");
var child = document.getElementById("child");
ele.innerHTML = "我是DOM節(jié)點(diǎn)"
console.log(child.nextSibling);
console.log(child.nextElementSibling);
console.log(child.previousSibling);
console.log(child.previousElementSibling);
</script>
UTOOLS1583589187092.png
DOM的案例
模態(tài)框
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
html,body{
height: 100%;
}
#box{
width: 100%;
height: 100%;
background: rgba(0,0,0,.3);
}
#content{
position: relative;
top: 150px;
width: 400px;
height: 200px;
line-height: 200px;
text-align: center;
color: red;
background-color: #fff;
margin: auto;
}
#span1{
position: absolute;
background-color: red;
top: 0;
right: 0;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
color: #fff;
}
</style>
</head>
<body>
<button id="btn">彈出</button>
</body>
<script type="text/javascript">
//獲取dom元素 1.獲取事件源
var oBtn = document.getElementById('btn');
//創(chuàng)建彈出模態(tài)框的相關(guān)DOM對象
var oDiv = document.createElement('div');
var oP = document.createElement('p');
var oSpan = document.createElement('span');
// 設(shè)置屬性
oDiv.id = 'box';
oP.id = 'content'
oP.innerHTML = '模態(tài)框成功彈出'
oSpan.innerHTML = 'X';
oSpan.id = 'span1'
// 追加元素
oDiv.appendChild(oP);
oP.appendChild(oSpan);
// 點(diǎn)擊彈出按鈕 彈出模態(tài)框
oBtn.onclick = function(){
//動態(tài)的添加到body中一個(gè)div
this.parentNode.insertBefore(oDiv,oBtn)
}
// 點(diǎn)擊X 關(guān)閉模態(tài)框
oSpan.onclick = function(){
// 移除oDiv元素
oDiv.parentNode.removeChild(oDiv)
}
</script>
</html>
1583589791351.gif
tab選項(xiàng)卡
<!DOCTYPE html>
<!--
* @Descripttion:
* @version:
* @Author: 小小熒
* @Date: 2020-03-06 21:20:00
* @LastEditors: 小小熒
* @LastEditTime: 2020-03-06 22:43:35
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
body {
margin: 0;
padding: 0;
}
#box {
width: 300px;
height: 200px;
border: 1px solid black;
margin: 0 auto;
}
.content {
text-align: center;
position: relative;
}
.content .box {
width: 100%;
height: 100%;
font-size: 100px;
line-height: 100px;
position: absolute;
display: none;
}
.btn.active {
color: aliceblue;
background: #000000;
}
.box.active {
display: block;
z-index: 1;
}
</style>
</head>
<body>
<div id="box">
<button class="btn active">1</button>
<button class="btn">2</button>
<button class="btn">3</button>
<div class="content">
<div class="box active">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
</div>
<script>
// 3.tab選項(xiàng)卡效果
/*
按鈕選中時(shí)會在按鈕上設(shè)置一個(gè)active的classname,這樣就會具有active的樣式,同時(shí)我們在將原牛對應(yīng)的內(nèi)容設(shè)置classname和之前的對應(yīng)的按鈕內(nèi)容的classname的active清除
*/
/**
* @name: removeClassName
* @test:
* @msg: 刪除之前的含有active的classname
* @param {type}
* @return:
*/
function removeClassName(btns, contents, classname) {
// 循環(huán)遍歷
for (var i = 0; i < btns.length; i++) {
// 獲取每一個(gè)按鈕的classnanmes
var btn_class_names = btns[i].getAttribute("class").split(" ");
var content_class_name = contents[i].getAttribute("class").split(" ");
// 如果找到了和這個(gè)class那么說明就是之前的那個(gè)active,我們需要把它的active的屬性值刪除然后重新為他設(shè)置未選中狀態(tài)的屬性值
var btn_index = btn_class_names.indexOf(classname);
var content_index = content_class_name.indexOf(classname);
if (btn_index !== -1) {
btn_class_names.splice(btn_index, 1);
// 處理完成之后我們在吧處理好的classname重新設(shè)置給按鈕的class
btns[i].className = btn_class_names.join(" ");
}
if (content_index !== -1) {
content_class_name.splice(content_index, 1);
contents[i].className = content_class_name.join(" ");
}
}
}
/**
* @name: toggleTab
* @test:
* @msg: 切換選項(xiàng)卡
* @param {type}
* @return:
*/
function toggleTab() {
// 獲取按鈕的節(jié)點(diǎn)
var btns = document.getElementsByClassName("btn");
// 獲取按鈕下方的內(nèi)容
var contents = document.querySelectorAll(".box");
// 循環(huán)監(jiān)聽按鈕點(diǎn)擊
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function (e) {
// 首先我們需要把清除之前的actIve的classname
removeClassName(btns, contents, "active");
// 將點(diǎn)擊的這個(gè)按鈕的class追加active屬性值
this.className += " active";
// 按鈕狀態(tài)設(shè)置完成之后在將按鈕對應(yīng)的內(nèi)容顯示出來,但是我們需要找到選中按鈕對用的內(nèi)容
var index = Array.from(btns).indexOf(this);
contents[index].className += " active";
}
}
}
// 調(diào)用切換選項(xiàng)卡函數(shù)
toggleTab();
</script>
</body>
</html>
1583589956352.gif
使用js完成偽元素標(biāo)簽的變色效果
<!DOCTYPE html>
<!--
* @Descripttion:
* @version:
* @Author: 小小熒
* @Date: 2020-03-07 22:07:31
* @LastEditors: 小小熒
* @LastEditTime: 2020-03-07 22:07:32
-->
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
button {
margin: 10px;
width: 100px;
height: 40px;
cursor: pointer;
}
.current {
background-color: red;
}
</style>
</head>
<body>
<button>按鈕1</button>
<button>按鈕2</button>
<button>按鈕3</button>
<button>按鈕4</button>
<button>按鈕5</button>
<script>
//需求:鼠標(biāo)放到哪個(gè)button上,改button變成黃色背景(添加類)
var btnArr = document.getElementsByTagName("button");
//綁定事件
for(var i=0;i<btnArr.length;i++){ //要為每一個(gè)按鈕綁定事件,所以用到了for循環(huán)
btnArr[i].onmouseover = function () {
//【重要】排他思想:先把所有按鈕的className設(shè)置為空,然后把我(this)這個(gè)按鈕的className設(shè)置為current
//排他思想和for循環(huán)連用
for(var j=0;j<btnArr.length;j++){
btnArr[j].className = "";
}
this.className = "current"; //【重要】核心代碼
}
}
//鼠標(biāo)離開current時(shí),還原背景色
for(var i=0;i<btnArr.length;i++){ //要為每一個(gè)按鈕綁定事件,所以用到了for循環(huán)
btnArr[i].onmouseout = function () { //鼠標(biāo)離開任何一個(gè)按鈕時(shí),就把按鈕的背景色還原
this.className = "";
}
}
</script>
</body>
</html>
1583590251334.gif