---
tags: API,DOM,第三章
---
# 串接API之DOM第三章
## DOM統整
創建
1.document.write
2.innerHTML
3.createElement
增
1.appendChild
2.insertBefore
刪
1.removeChild
改
1.修改元素屬性:src、href、title
2.修改普通元素內容:innerHTML、innerText
3.修改表單元素:value、type、disabled
4.修改元素樣式:style、className
查
1.DOM舊方法:getElementById、getElementsByTagName
2.H5新方法:querySelector、querySelectorAll
3.利用節點
父:parentNode
子:children
兄:previousElementSibling、nextElementSibling
屬性操作
1.setAttribute設置
2.getAttribute得到
3.removeAttribute移除
事件操作
| 鼠標事件 | 觸發條件 |
| ----------- | ---------------- |
| onclick | 滑鼠點擊左鍵觸發 |
| onmouseover | 滑鼠經過觸發 |
| onmouseout | 滑鼠離開觸發 |
| onfocus | 獲得滑鼠焦點觸發 |
| onblur | 失去滑鼠焦點觸發 |
| onmousemove | 滑鼠移動觸發 |
| onmouseup | 滑鼠彈起觸發 |
| onmousedown | 滑鼠按下觸發 |
## 三種動態創建元素
### document.write()
會導致頁面重繪
```
<body>
<button>點擊</button>
<p>abc</p>
<script>
var btn = document.querySelector('button');
btn.onclick = function () {
document.write('<div>123</div>');
};
</script>
</body>
```
### element.innerHTML
測速:約770毫秒
```
<body>
<script>
function fn() {
var d1 = +new Date();
var str = '';
for (var i = 0; i < 1000; i++) {
document.body.innerHTML +=
'<div style="width: 100px; height: 2px; border: 1px solid blue;"></div>';
}
var d2 = +new Date();
console.log(d2 - d1);
}
fn();
</script>
</body>
```
測速:約1毫秒
```
<body>
<script>
function fn() {
var d1 = +new Date();
var array = [];
for (var i = 0; i < 1000; i++) {
array.push(
'<div style="width: 100px; height: 2px; border: 1px solid blue;"></div>'
);
}
document.body.innerHTML = array.join('');
var d2 = +new Date();
console.log(d2 - d1);
}
fn();
</script>
</body>
```
### document.createElement()
測速:約5毫秒
```javascript=
function fn() {
var d1 = +new Date();
for (var i = 0; i < 1000; i++) {
var div = document.createElement('div');
div.style.width = '100px';
div.style.height = '2px';
div.style.border = '1px solid red';
document.body.appendChild(div);
}
var d2 = +new Date();
console.log(d2 - d1);
}
fn();
```
### 總結
```
<body>
<div class="inner"></div>
<div class="create"></div>
<script>
var inner = document.querySelector('.inner');
for (i = 1; i <= 100; i++) {
inner.innerHTML = '<a href="#">百度</a>';
}
var create = document.querySelector('.create');
for (var i = 1; i <= 100; i++) {
var a = document.createElement('a');
create.appendChild(a);
}
</script>
</body>
```
```
<body>
<div class="inner"></div>
<div class="create"></div>
<script>
var inner = document.querySelector('.inner');
var arr =[]
for (i = 1; i <= 100; i++){
arr.push('<a href="#">百度</a>')
}
inner.innerHTML=arr.join('');
var create = document.querySelector('.create');
for (var i = 1; i <= 100; i++) {
var a = document.createElement('a');
create.appendChild(a);
}
</script>
</body>
```
## 註冊事件2種方式
### 傳統註冊
具有唯一性
```
<body>
<button onclick="alert('hi')">按我</button>
</body>
```
```
<body>
<button onclick="alert('hi')">按我</button>
<button>2號</button>
<script>
var btn = document.querySelectorAll('button');
btn[1].onclick = function () {
alert('hello');
};
</script>
</body>
```
```
<body>
<button onclick="alert('hi')">按我</button>
<button>2號</button>
<script>
var btn = document.querySelectorAll('button');
btn[1].onclick = function () {
alert('hello');
};
// 前面的被覆蓋了
btn[1].onclick = function () {
alert('see');
};
</script>
</body>
```
### 方法監聽註冊
w3c標準
同元素同事件可以註冊多個監聽器
```
eventTarget.addEventListener(type,listener[,useCapture])
```
eventTarget目標對象
type事件類型字符串,比如click、mouseover,注意不要帶on
listener事件處理函數
useCapture可選參數,是一個布林值(默認false)
```
<body>
<button>安安</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function () {
alert('100');
});
btn.addEventListener('click', function () {
alert('200');
});
</script>
</body>
```
### ie9舊方法(不要用)
非標準
```
eventTarget.attachEvent(eventNameWithOn,callback)
```
eventNameWithOn事件類型字符串,比如onclick、onmouseover,注意有on
callback事件處理函數
```
<body>
<button>安安</button>
<script>
var btn = document.querySelector('button');
btn.attachEvent('onclick', function () {
alert('100');
})
</script>
</body>
```
## 刪除事件
傳統方法
```
eventTarget.onclick = null;
```
監聽註冊方法
```
eventTarget.removeEventListener(type,listener[,useCapture])
```
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
div {
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div>1</div>
<div>2</div>
<script>
var divs = document.querySelectorAll('div');
divs[0].onclick = function () {
alert(11);
divs[0].onclick = null;
};
divs[1].addEventListener('click', fn); // 裡面的fn不用加小括號調用
function fn() {
alert(22);
divs[1].removeEventListener('click', fn);
}
</script>
</body>
</html>
```
## 事件流


1.JS單次只能執行捕獲或冒泡其中一階段
2.onclick和attachEvent只能得到冒泡階段
3.實際開發比較關注冒泡
4.有些事件沒有冒泡,如onblur、onfocus、onmouseenter、onmouseleave
eventTarget.addEventListener(type,listener[,useCapture])
第三個參數是true就在捕獲階段調用
第三個參數是false就在冒泡階段調用
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.father {
width: 800px;
height: 800px;
background-color: pink;
}
.son {
width: 400px;
height: 400px;
background-color: green;
}
</style>
</head>
<body>
<div class="father">
<div class="son">123</div>
</div>
<script>
// 捕獲
var son = document.querySelector('.son');
son.addEventListener(
'click',
function () {
alert('son');
},
true
);
var father = document.querySelector('.father');
father.addEventListener(
'click',
function () {
alert('father');
},
true
);
// 冒泡
var son = document.querySelector('.son');
son.addEventListener(
'click',
function () {
alert('son');
},
false
);
var father = document.querySelector('.father');
father.addEventListener(
'click',
function () {
alert('father');
},
false
);
document.addEventListener('click', function () {
alert('document');
});
</script>
</body>
</html>
```
## 事件對象
1.event事件對象,寫到監聽函數小括號裡,當型參看
2.有了事件才有事件對象,是系統自動創建,我們不用傳遞參數
3.事件對象是事件的相關數據集合
4.事件對象可以自己命名,如event、evt、e
```
<body>
<div>123</div>
<script>
var div = document.querySelector('div');
div.onclick = function (event) {
console.log(event);
};
div.addEventListener('click', function (e) {
console.log(e);
});
</script>
</body>
```
## 區別
e.target標準
e.srcElement非標準
e.currentTarget少用
```
<body>
<div>123</div>
<ul>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<script>
var div = document.querySelector('div');
div.addEventListener('click', function (e) {
console.log(e.target);
console.log(this);
});
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
// e.target指向點擊的對象
console.log(e.target);
// this指向綁定事件的對象
console.log(this);
// e.currentTarget跟this很像
console.log(e.currentTarget);
});
</script>
</body>
```
## 阻止默認行為
e.type返回事件的類型,如click、mouseover不帶on
e.preventDefault()標準
e.returnValue非標準
```
<body>
<div>123</div>
<a href="https://www.google.com/">google</a>
<form action="https://www.google.com/">
<input type="submit" value="提交" name="sub" />
</form>
<script>
var div = document.querySelector('div');
div.addEventListener('click', fn);
div.addEventListener('mouseover', fn);
div.addEventListener('mouseout', fn);
function fn(e) {
console.log(e.type);
}
// 阻止默認
var a = document.querySelector('a');
a.addEventListener('click', function (e) {
e.preventDefault();
});
// 傳統方法
a.onclick = function (e) {
return false;
alert(11); // 不執行
};
</script>
</body>
```
## 阻止冒泡
e.stopPropagation()標準
e.cancelBubble非標準
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.father {
width: 800px;
height: 800px;
background-color: pink;
}
.son {
width: 400px;
height: 400px;
background-color: green;
}
</style>
</head>
<body>
<div class="father">
<div class="son">123</div>
</div>
<script>
// 捕獲
var son = document.querySelector('.son');
son.addEventListener(
'click',
function () {
alert('son');
},
true
);
var father = document.querySelector('.father');
father.addEventListener(
'click',
function () {
alert('father');
},
true
);
// 冒泡
var son = document.querySelector('.son');
son.addEventListener(
'click',
function (e) {
alert('son');
e.stopPropagation();
},
false
);
var father = document.querySelector('.father');
father.addEventListener(
'click',
function () {
alert('father');
},
false
);
document.addEventListener('click', function () {
alert('document');
});
</script>
</body>
</html>
```
## 冒泡簡單應用
```
<body>
<ul>
<li>天線寶寶說你好</li>
<li>天線寶寶說你好</li>
<li>天線寶寶說你好</li>
<li>天線寶寶說你好</li>
<li>天線寶寶說你好</li>
<li>天線寶寶說你好</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
alert('天線寶寶說你好');
e.target.style.backgroundColor = 'pink';
});
</script>
</body>
```
## 進階鼠標事件
```
<body>
我是一段不願意被分享的文字
<script>
// 1.禁止右鍵菜單
document.addEventListener('contextmenu', function (e) {
e.preventDefault();
});
// 2.禁止滑鼠選中
document.addEventListener('selectstart', function (e) {
e.preventDefault();
});
</script>
</body>
```
## 滑鼠座標
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
height: 3000px;
}
</style>
</head>
<body>
<script>
document.addEventListener('click', function (e) {
// 1.可視區的x和y座標
console.log(e.clientX);
console.log(e.clientY);
console.log('----------');
// 2.頁面文檔的x和y座標
console.log(e.pageX);
console.log(e.pageY);
console.log('----------');
// 2.電腦螢幕的x和y座標
console.log(e.screenX);
console.log(e.screenY);
});
</script>
</body>
</html>
```
## 案例:滑鼠天使
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
img {
position: absolute;
cursor: none;
}
</style>
</head>
<body>
<img src="greenman.gif" alt="" />
<script>
var pic = document.querySelector('img');
document.addEventListener('mousemove', function (e) {
var x = e.pageX;
var y = e.pageY;
pic.style.left = x - 10 + 'px';
pic.style.top = y - 10 + 'px';
});
</script>
</body>
</html>
```
## 鍵盤事件
(優先順序3)onkeyup
(優先順序1)onkeydown
(優先順序2)onkeypress(不識別功能鍵ctrl shift 箭頭)
```
<body>
<script>
document.onkeyup = function () {
console.log('我彈起了');
};
document.addEventListener('keyup', function () {
console.log('彈');
});
document.addEventListener('keydown', function () {
console.log('按down');
});
document.addEventListener('keypress', function () {
console.log('按press');
});
</script>
</body>
```
## keyCode
查ASCII碼
http://c.biancheng.net/c/ascii/
onkeyup不區分英文大小寫
onkeydown不區分英文大小寫
onkeypress區分英文大小寫
```
<body>
<script>
document.addEventListener('keyup', function (e) {
console.log(e);
console.log(e.keyCode);
});
document.addEventListener('keydown', function (e) {
console.log('down' + e.keyCode);
});
document.addEventListener('keypress', function (e) {
console.log('press' + e.keyCode);
});
</script>
</body>
```
## 模擬京東搜尋
focus()獲得焦點
```
<body>
<input type="text" />
<script>
var search = document.querySelector('input');
document.addEventListener('keyup', function (e) {
if (e.keyCode === 83) {
search.focus();
}
});
</script>
</body>
```
## 快遞單號放大鏡
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.search {
position: relative;
width: 178px;
margin: 100px;
}
.con {
display: none;
position: absolute;
top: -40px;
width: 171px;
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
padding: 5px 0;
font-size: 18px;
line-height: 20px;
color: #333;
}
.con::before {
content: '';
width: 0;
height: 0;
position: absolute;
top: 28px;
left: 18px;
border: 8px solid #000;
border-style: solid dashed dashed;
border-color: #fff transparent transparent;
}
</style>
</head>
<body>
<div class="search">
<div class="con">123</div>
<input type="text" placeholder="快遞單號" class="jd" />
</div>
<script>
var con = document.querySelector('.con');
var jd_input = document.querySelector('.jd');
jd_input.addEventListener('keyup', function () {
if (this.value == '') {
con.style.display = 'none';
} else {
con.style.display = 'block';
con.innerText = this.value;
}
});
jd_input.addEventListener('blur', function () {
con.style.display = 'none';
});
jd_input.addEventListener('focus', function () {
if (this.value !== '') {
con.style.display = 'block';
}
});
</script>
</body>
</html>
```