JS 的組成

1. Web API介紹
1.1 API的概念
-
API(Application Programming Interface,應(yīng)用程序編程接口)是一些預(yù)先定義的函數(shù),目的是提供應(yīng)用程序與開發(fā)人員基于某軟件或硬件得以訪問一組例程的能力,而又無需訪問源碼,無需理解其內(nèi)部工作機(jī)制細(xì)節(jié),只需直接調(diào)用使用即可。

1.2 Web API的概念
Web API是瀏覽器提供的一套操作瀏覽器功能和頁面元素的API(BOM和DOM)。現(xiàn)階段我們主要針對于瀏覽器講解常用的
API, 主要針對瀏覽器做交互效果。比如我們想要瀏覽器彈出一個警示框, 直接使用alert(‘彈出’)。此處的 Web API 特指瀏覽器提供的一系列API(很多函數(shù)或?qū)ο蠓椒?,即操作網(wǎng)頁的一系列工具。例如:操作html標(biāo)簽、操作頁面地址的方法。
1.3 API 和 Web API 總結(jié)
API 是為我們程序員提供的一個接口,幫助我們實現(xiàn)某種功能,我們會使用就可以了,不必糾結(jié)內(nèi)部如何實現(xiàn);
Web API 主要是針對于瀏覽器提供的接口,主要針對于瀏覽器做交互效果。;
Web API 一般都有輸入和輸出(函數(shù)的傳參和返回值),Web API 很多都是方法(函數(shù));
學(xué)習(xí) Web API 可以結(jié)合前面學(xué)習(xí)內(nèi)置對象方法的思路學(xué)習(xí)。
2. DOM 介紹
2.1 什么是DOM
文檔對象模型(
Document Object Model,簡稱DOM),是 W3C 組織推薦的處理可擴(kuò)展標(biāo)記語言(html或者xhtml)的標(biāo)準(zhǔn)編程接口。W3C已經(jīng)定義了一系列的DOM接口,通過這些DOM接口可以改變網(wǎng)頁的內(nèi)容、結(jié)構(gòu)和樣式。DOM是W3C組織制定的一套處理html和xml文檔的規(guī)范,所有的瀏覽器都遵循了這套標(biāo)準(zhǔn)。
2.2 DOM樹

-
DOM樹 又稱為文檔樹模型,把文檔映射成樹形結(jié)構(gòu),通過節(jié)點對象對其處理,處理的結(jié)果可以加入到當(dāng)前的頁面。
- 文檔:一個頁面就是一個文檔,
DOM中使用document表示;- 節(jié)點:網(wǎng)頁中的所有內(nèi)容,在文檔樹中都是節(jié)點(標(biāo)簽、屬性、文本、注釋等),使用
node表示;- 標(biāo)簽節(jié)點:網(wǎng)頁中的所有標(biāo)簽,通常稱為元素節(jié)點,又簡稱為“元素”,使用
element表示。
3. 獲取元素
為什么要獲取頁面元素?
- 例如:我們想要操作頁面上的某部分(顯示/隱藏,動畫),需要先獲取到該部分對應(yīng)的元素,再對其進(jìn)行操作。
3.1 根據(jù)ID獲取
語法:
document.getElementById(id);
作用:根據(jù)ID獲取元素對象;
參數(shù):id值,區(qū)分大小寫的字符串;
返回值:元素對象 或null。
案例代碼
<div id="time">2020-11-29</div>
<script>
// 1. 因為我們文檔頁面從上往下加載的,所以需要先有標(biāo)簽
let timeDiv = document.getElementById('time');
console.log(typeof timeDiv); // Object
console.dir(timeDiv); // 打印返回的元素對象
</script>
3.2 根據(jù)標(biāo)簽名獲取元素
語法:
document.getElementsByTagName('標(biāo)簽名')或者element.getElementsByTagName('標(biāo)簽名');
作用:根據(jù)標(biāo)簽名獲取元素對象;
參數(shù):標(biāo)簽名;
返回值:元素對象集合(偽數(shù)組,數(shù)組元素是元素對象)。
案例代碼
<body>
<ul id="first">
<li>知否知否</li>
<li>知否知否</li>
<li>知否知否</li>
<li>知否知否</li>
<li>知否知否</li>
</ul>
<ul id="second">
<li>哈哈哈哈</li>
<li>哈哈哈哈</li>
<li>哈哈哈哈</li>
<li>哈哈哈哈</li>
<li>哈哈哈哈</li>
<li>哈哈哈哈</li>
</ul>
<script>
let liTag = document.getElementsByTagName('li');
console.log(liTag);
// 打印里面的元素
for (let i = 0; i < liTag.length; i++) {
console.log(liTag[i]);
}
// 如果執(zhí)行獲取第二個ul中的li
let secondUl = document.getElementById('second');
let secondLi = secondUl.getElementsByTagName('li');
// 打印里面的元素
for (let i = 0; i < secondLi.length; i++) {
console.log(secondLi[i]);
}
</script>
</body>
注意:getElementsByTagName()獲取到是動態(tài)集合,即:當(dāng)頁面增加了標(biāo)簽,這個集合中也就增加了元素。
3.3 H5新增獲取元素方式

注意:querySelector和querySelectorAll里面的選擇器需要加上選擇器對應(yīng)的符號,比如:document.querySelector('#nav')
案例代碼
<body>
<div class="box">盒子1</div>
<div class="box">盒子2</div>
<div id="nav">
<ul>
<li>首頁</li>
<li>產(chǎn)品</li>
</ul>
</div>
<script>
/* H5新增獲取元素的方法 */
let boxs = document.getElementsByClassName('box');
console.log(boxs);
/* querySelector返回指定選擇器的第一個元素對象切記里面的選擇器需要加上指定的符號 */
let firstBox = document.querySelector('.box');
console.log(firstBox);
let nav = document.querySelector('#nav');
console.log(nav);
let firstLi = document.querySelector('li');
console.log(firstLi);
/* 返回指定選擇器的所有元素對象 */
let boxList = document.querySelectorAll('.box');
console.log(boxList);
let lis = document.querySelectorAll('li');
console.log(lis);
</script>
</body>
3.4 獲取特殊元素
- 獲取body元素:
let bodyEle = document.body;
- 獲取html元素:
let htmlEle = document.documentElement;
4. 事件基礎(chǔ)
4.1 事件概述
JavaScript使我們有能力創(chuàng)建動態(tài)頁面,而事件是可以被JavaScript偵測到的行為。簡單理解: 觸發(fā)--- 響應(yīng)機(jī)制 。
網(wǎng)頁中的每個元素都可以產(chǎn)生某些可以觸發(fā)
JavaScript的事件,例如,我們可以在用戶點擊某按鈕時產(chǎn)生一個 事件,然后去執(zhí)行某些操作。
4.2 事件三要素
事件源(誰):觸發(fā)事件的元素;
事件類型(什么事件): 例如 click 點擊事件;
事件處理程序(做啥):事件觸發(fā)后要執(zhí)行的代碼(函數(shù)形式),事件處理函數(shù)。
案例代碼
- 點擊一個案例彈出一個
alert()提示框。
<body>
<button id="btn">點我</button>
<script>
// 點擊一個按鈕彈出對話框
// 1. 事件是由三部分組成的 事件源 事件類型 事件處理程序
// a. 事件源 事件被處罰的對象
let btn = document.getElementById('btn');
// b. 事件類型 :如何觸發(fā)什么事件 比如鼠標(biāo)點擊還是鼠標(biāo)經(jīng)過
// c. 事件處理程序
btn.onclick = function () {
alert('您點我了!')
}
</script>
</body>
4.3 執(zhí)行事件的步驟
獲取事件源;
注冊事件;
添加事件處理程序(采取函數(shù)形式賦值)。
案例代碼
<body>
<div>123</div>
<script>
// 事件執(zhí)行的步驟
// 點擊div 控制臺輸出我被選中了
// 1. 獲取事件源
// 使用 document.getElementsByTagName('div') 獲取到的div 元素注冊的事件不生效
let div = document.querySelector('div');
console.log(div);
// 2. 綁定事件 注冊事件
// div.onclick
// 3. 添加事件處理程序
div.onclick = function () {
console.log('我被選中了');
}
</script>
</body>
4.4 常見的鼠標(biāo)事件

5. 操作元素
-
JavaScript的DOM操作可以改變網(wǎng)頁內(nèi)容、結(jié)構(gòu)和樣式,我們可以利用DOM操作元素來改變元素里面的內(nèi)容、屬性等。(注意:這些操作都是通過元素對象的屬性實現(xiàn)的)。
5.1 改變元素內(nèi)容(獲取或設(shè)置)

操作元素之改變元素內(nèi)容
<body>
<button>點擊獲取時間</button>
<div>****-**-** **:**:**</div>
<script>
let btn = document.querySelector('button');
let div = document.querySelector('div');
btn.onclick = function () {
// 設(shè)置元素的內(nèi)容為當(dāng)前時間
div.innerText = getDate();
}
function getDate() {
let date = new Date();
let year = date.getFullYear(); // 獲取當(dāng)前的年份
let month = formatDate(date.getMonth() + 1); // 獲取月份 需要進(jìn)行 +1
let dates = formatDate(date.getDate()); // 獲取日
let weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
let day = date.getDay(); // 獲取今天是星期幾
let hour = formatDate(date.getHours());
let minutes = formatDate(date.getMinutes());
let seconds = formatDate(date.getSeconds());
return '今天是:' + year + '年' + month + '月' + dates + '日' + ' ' + hour + ':' + minutes + ':' + seconds + ' ' + weeks[day];
}
function formatDate(param) {
return param < 10 ? '0' + param : param;
}
</script>
</body>
innerText和innerHTML的區(qū)別
獲取內(nèi)容時的區(qū)別:
innerText會去除空格和換行,而innerHTML會保留空格和換行;設(shè)置內(nèi)容時的區(qū)別:
innerText不會識別html,而innerHTML會識別。W3C標(biāo)準(zhǔn)。這兩個屬性都是可讀寫的,既可以通過他們設(shè)置內(nèi)容也可以通過他們獲取內(nèi)容。
<body>
<button>點我</button>
<div></div>
<p>
p標(biāo)簽
<span>
哈哈哈哈
</span>
</p>
<script>
// innerText 和 innerHTML 的區(qū)別
// 1. innerText 不識別html標(biāo)簽 并且去除空格和換行,非標(biāo)準(zhǔn)
let btn = document.querySelector('button');
let div = document.querySelector('div');
btn.onclick = function () {
// div.innerText = '<strong>加粗</strong> : 123'; // 不識別 html 標(biāo)簽
div.innerHTML = '<strong>加粗</strong> : 123';
}
// 2. innerHtml 識別html標(biāo)簽,W3C標(biāo)準(zhǔn)
// 3. 這兩個屬性是可讀寫的,可以獲取元素里面的內(nèi)容
// a. 通過 innerText 獲取
let p = document.querySelector('p');
let pInnerText = p.innerText;
let pInnerHtml = p.innerHTML;
console.log(pInnerText); // 結(jié)果 p標(biāo)簽 哈哈哈哈
console.log(pInnerHtml); // 結(jié)果 p標(biāo)簽<span>哈哈哈哈</span>
</script>
</body>
5.2 常用元素的屬性操作

獲取屬性的值
元素對象.屬性名
設(shè)置屬性的值
元素對象.屬性名=值
案例代碼
<body>
<button id="ldh">劉德華</button>
<button id="zxy">張學(xué)友</button>
<img src="../images/ldh.jpg" alt="劉德華" title="劉德華">
<script>
let ldh = document.querySelector('#ldh');
let zxy = document.querySelector('#zxy');
let img = document.querySelector('img');
ldh.onclick = function () {
img.src = '../images/ldh.jpg';
img.title = '劉德華';
img.alt = '劉德華';
};
zxy.onclick = function () {
img.src = '../images/zxy.jpg';
img.title = '張學(xué)友';
img.alt = '張學(xué)友';
};
</script>
</body>
5.3 案例:分時問候
- 在不同的時間段內(nèi)顯示不同的圖片和問候語:
<body>
<img src="../images/w.gif" alt="">
<div>晚上好</div>
<script>
let img = document.querySelector('img');
let div = document.querySelector('div');
let date = new Date();
let h = date.getHours();
if (h < 12) {
img.src = '../images/z.gif';
div.innerHTML = '早上好';
} else if (h < 18) {
img.src = '../images/x.gif';
div.innerHTML = '下午好';
} else {
img.src = '../images/w.gif';
div.innerHTML = '晚上好';
}
</script>
</body>
5.4 表單元素的屬性操作

獲取屬性的值
元素對象.屬性名
設(shè)置屬性的值
元素對象.屬性名 = 值
表單元素中有一些屬性如:disabled、checked、selected,元素對象的這些屬性的值是布爾型。
案例代碼
<body>
<button>按鈕</button>
<input type="text" value="請輸入內(nèi)容">
<script>
// this指向當(dāng)前事件函數(shù)的調(diào)用者
let button = document.querySelector('button');
let input = document.querySelector('input');
/**
* 處理button的單擊事件
*/
button.onclick = function () {
// 點擊一次之后就將其禁用
this.disabled = true;
input.value = '被點擊了';
}
</script>
</body>
5.5 案例:仿京東顯示隱藏密碼
-
點擊右側(cè)的顯示或隱藏按鈕顯示或隱藏文本框中的密碼:
隱藏密碼

<style>
.box {
position: relative;
width: 400px;
margin: 100px auto;
border-bottom: 1px solid #cccccc;
}
.box input {
width: 370px;
height: 30px;
outline: none;
border: none;
padding-left: 20px;
}
.box img {
position: absolute;
top: 2px;
right: 6px;
width: 24px;
cursor: pointer;
}
/* 去除密碼框的默認(rèn)小眼睛樣式 */
input[type="password"]::-ms-reveal {
display: none
}
</style>
<body>
<div class="box">
<label for="password">
<img src="../../images/close.png" alt="" id="eye">
<input type="password" id="password">
</label>
</div>
<script>
let pwd = document.getElementById('password');
let eye = document.getElementById('eye');
let flag = 0;
eye.onclick = function () {
if (flag === 0) {
pwd.type = 'password';
this.src = '../../images/close.png';
flag = 1;
} else {
pwd.type = 'text';
this.src = '../../images/open.png';
flag = 0;
}
}
</script>
</body>
5.6 樣式屬性操作
- 當(dāng)觸發(fā)單擊事件時,改變
div樣式。
<style>
div {
width: 200px;
height: 200px;
background-color: skyblue;
}
</style>
<body>
<div></div>
<script>
// 1. 獲取元素
let div = document.querySelector('div');
// 2. 注冊事件 // 3. 處理程序
div.onclick = function () {
// 行內(nèi)樣式 JS修改style樣式操作產(chǎn)生的是行內(nèi)樣式,CSS權(quán)重比較高
this.style.backgroundColor = 'purple';
this.style.width = '230px';
}
</script>
</body>
- 我們可以通過
JS修改元素的大小、顏色、位置等樣式。
常用方式
element.style行內(nèi)樣式。element.className類名樣式。如果原來的className中有類名樣式,此操作將對其進(jìn)行覆蓋。
通過操作style屬性
元素對象的style屬性也是一個對象!
元素對象.style.樣式屬性 = 值;
注意:JS 里面的樣式采用駝峰命名法,比如fontSize 、 backgroundColor。
JS修改Style樣式操作,產(chǎn)生的行內(nèi)樣式CSS權(quán)重比較高。
5.7 案例:淘寶點擊關(guān)閉二維碼
- 當(dāng)鼠標(biāo)點擊二維碼關(guān)閉按鈕的時候則關(guān)閉整個二維碼:

<style>
.box {
position: relative;
width: 200px;
height: 200px;
margin: 100px auto;
border: 1px solid #ccc;
text-align: center;
color: #EF522F;
border-radius: 6px;
-webkit-border-radius: 6px;
box-sizing: border-box;
}
.box img {
margin-top: 5px;
}
.box i {
position: absolute;
width: 20px;
height: 20px;
border: 1px solid #ccc;
left: -25px;
color: #ccc;
border-radius: 2px;
cursor: pointer;
}
</style>
<body>
<div class="box">
淘寶二維碼
<img src="../images/tao.png" alt="">
<i class="close_btn" id="iBtn">x</i>
</div>
<script>
let iBtn = document.getElementById('iBtn');
let box = document.querySelector('.box');
iBtn.onclick = function () {
box.style.display = 'none';
}
</script>
</body>
5.8 案例 :循環(huán)精靈圖
- 可以利用for循環(huán)設(shè)置一組 元素的精靈圖背景:

<style>
ul {
list-style: none;
padding: 0;
margin: 0;
}
li {
padding: 0;
margin: 0;
}
.box {
width: 250px;
margin: 100px auto;
}
.box li {
float: left;
width: 24px;
height: 24px;
margin: 15px;
background-image: url(../images/sprite.png);
}
</style>
<body>
<div class="box">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<script>
let lis = document.querySelectorAll('li');
for (let i = 0; i < lis.length; i++) {
let index = i * 44;
lis[i].style.backgroundPosition = '0 -' + index + 'px';
}
</script>
</body>
5.9 案例:顯示和隱藏文本框內(nèi)容
- 當(dāng)鼠標(biāo)點擊文本框時,里面默認(rèn)文字隱藏,當(dāng)鼠標(biāo)離開文本框時,里面文字顯示。

<body>
<input type="text" value="手機(jī)">
<script>
let text = document.querySelector('input');
/**
* 當(dāng)文本框獲取焦點的時候
*/
text.onfocus = function () {
if (this.value === '手機(jī)') {
this.value = '';
}
// 當(dāng)輸入文字之后文字顏色變黑
this.style.color = '#333';
}
/**
* 鼠標(biāo)失去焦點事件
*/
text.onblur = function () {
if (this.value === '') {
this.value = '手機(jī)';
}
// 當(dāng)鼠標(biāo)移開時文字顏色變淺
this.style.color = '#999'
}
</script>
</body>
通過操作className屬性
元素對象.className = 值;
因為class是關(guān)鍵字,所有使用className。
注意
如果樣式修改較多的時候可以采取操作類名的方式更改元素樣式。
class因為是保留字 ,因此使用className來操作元素 類名屬性。className會直接更改元素的類名,會覆蓋原先的類名。
案例代碼
<style>
div {
width: 200px;
height: 200px;
background-color: skyblue;
}
.change {
background-color: purple;
margin-top: 100px;
color: #fff;
}
</style>
<body>
<div class="first">文本</div>
<script>
let changeClassName = document.querySelector('div');
changeClassName.onclick = function () {
// 可以通過修改元素的className更改元素的樣式適合于樣式較多或者功能復(fù)雜的情況
// 會直接覆蓋原來的類名
// 如果想要保留原先的類名 可以這么做
// this.className = 'change';
this.className = 'first change';
// this.className += ' ' + 'change';
}
</script>
</body>
5.10 案例:密碼框格式提示錯誤信息
- 用戶如果離開密碼框,里面輸入 個數(shù)不是6~16時,提示錯誤信息,否則提示輸入正確信息。


<style>
div {
width: 600px;
margin: 100px auto;
}
.message {
display: inline-block;
background: url(../images/mess.png) left center no-repeat;
padding-left: 20px;
font-size: 12px;
color: #999;
vertical-align: middle;
}
.wrong {
background-image: url(../images/wrong.png);
color: #f00;
}
.right {
background-image: url(../images/right.png);
color: #0f0;
}
</style>
<body>
<div class="registry">
<input type="password" class="ipt">
<p class="message">請輸入6~16位的密碼!</p>
</div>
<script>
let ipt = document.querySelector('.ipt');
let message = document.querySelector('.message');
ipt.onblur = function () {
if (this.value.length < 6 || this.value.length > 16) {
message.className = 'message wrong';
message.innerHTML = '您輸入的不符合規(guī)范!'
} else {
message.className = 'message right';
message.innerHTML = '您輸入正確!'
}
}
</script>
</body>
