8.1 常用鍵盤事件
事件除了使用滑鼠觸發,還可以使用鍵盤觸發,

注意:
- 如果使用addEventListener 不需要加 on
onkeypress 和前面2個的區別是,它不識別功能鍵,比如左右箭頭,shift 等,
三個事件的執行順序是: keydown – keypress — keyup
8.2 鍵盤事件物件

注意: onkeydown 和 onkeyup 不區分字母大小寫,onkeypress 區分字母大小寫,
在我們實際開發中,我們更多的使用keydown和keyup, 它能識別所有的鍵(包括功能鍵)
Keypress 不識別功能鍵,但是keyCode屬性能區分大小寫,回傳不同的ASCII值
案例: 模擬京東按鍵輸入內容
核心思路: 檢測用戶是否按下了s 鍵,如果按下s 鍵,就把游標定位到搜索框里面
使用鍵盤事件物件里面的keyCode 判斷用戶按下的是否是s鍵
搜索框獲得焦點: 使用 js 里面的 focus() 方法
<!DOCTYPE html>
<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>
</head>
<body>
<input type="text">
<script>
// 核心思路: 檢測用戶是否按下了s 鍵,如果按下s 鍵,就把游標定位到搜索框里面
// 使用鍵盤事件物件里面的keyCode 判斷用戶按下的是否是s鍵
// 搜索框獲得焦點: 使用 js 里面的 focus() 方法
var search = document.querySelector('input');
document.addEventListener('keyup', function(e) {
// console.log(e.keyCode);
if (e.keyCode === 83) {
search.focus();
}
})
</script>
</body>
</html>
案例: 模擬京東快遞單號查詢

快遞單號輸入內容時, 上面的大號字體盒子(con)顯示(這里面的文字
同時把快遞單號里面的值(value)獲取過來賦值給 con盒子(innerText)做為內容
如果快遞單號里面內容為空,則隱藏大號字體盒子(con)盒子
<!DOCTYPE html>
<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>
* {
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, .2);
box-shadow: 0 2px 4px rgba(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>
// 快遞單號輸入內容時, 上面的大號字體盒子(con)顯示(這里面的字號更大)
// 表單檢測用戶輸入: 給表單添加鍵盤事件
// 同時把快遞單號里面的值(value)獲取過來賦值給 con盒子(innerText)做為內容
// 如果快遞單號里面內容為空,則隱藏大號字體盒子(con)盒子
var con = document.querySelector('.con');
var jd_input = document.querySelector('.jd');
jd_input.addEventListener('keyup', function() {
// console.log('輸入內容啦');
if (this.value == '') {
con.style.display = 'none';
} else {
con.style.display = 'block';
con.innerText = this.value;
}
})
// 當我們失去焦點,就隱藏這個con盒子
jd_input.addEventListener('blur', function() {
con.style.display = 'none';
})
// 當我們獲得焦點,就顯示這個con盒子
jd_input.addEventListener('focus', function() {
if (this.value !== '') {
con.style.display = 'block';
}
})
</script>
</body>
1.1 什么是 BOM
BOM(Browser Object Model)即瀏覽器物件模型,它提供了獨立于內容而與瀏覽器視窗進行互動的物件,其核心物件是 window,
BOM 由一系列相關的物件構成,并且每個物件都提供了很多方法與屬性,
BOM 缺乏標準,JavaScript 語法的標準化組織是 ECMA,DOM 的標準化組織是 W3C,BOM 最初是Netscape 瀏覽器標準的一部分,
DOM:
檔案物件模型
DOM 就是把「檔案」當做一個「物件」來看待
DOM 的頂級物件是 document
DOM 主要學習的是操作頁面元素
DOM 是 W3C 標準規范
BOM:
瀏覽器物件模型
把「瀏覽器」當做一個「物件」來看待
BOM 的頂級物件是 window
BOM 學習的是瀏覽器視窗互動的一些物件
BOM 是瀏覽器廠商在各自瀏覽器上定義的,兼容性較差
1.2 BOM 的構成
BOM 比 DOM 更大,它包含 DOM,


2. window 物件的常見事件
2.1 視窗加載事件

window.onload 是視窗 (頁面)加載事件,當檔案內容完全加載完成會觸發該事件(包括影像、腳本檔案、CSS 檔案等), 就呼叫的處理函式,
注意:
- 有了 window.onload 就可以把 JS 代碼寫到頁面元素的上方,因為 onl oad 是等頁面內容全部加載完畢,再去執行處理函式,
- window.onload 傳統注冊事件方式 只能寫一次,如果有多個,會以最后一個 window.onload 為準,
- 如果使用 addEventListener 則沒有限制
<!DOCTYPE html>
<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>
<script>
// window.onload = function() {
// var btn = document.querySelector('button');
// btn.addEventListener('click', function() {
// alert('點擊我');
// })
// }
// window.onload = function() {
// alert(22);
// }
window.addEventListener('load', function() {
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
alert('點擊我');
})
})
window.addEventListener('load', function() {
alert(22);
})
document.addEventListener('DOMContentLoaded', function() {
alert(33);
})
// load 等頁面內容全部加載完畢,包含頁面dom元素 圖片 flash css 等等
// DOMContentLoaded 是DOM 加載完畢,不包含圖片 falsh css 等就可以執行 加載速度比 load更快一些
</script>
</head>
<body>
<button>點擊</button>
</body>
</html>

DOMContentLoaded 事件觸發時,僅當DOM加載完成,不包括樣式表,圖片,flash等等,
Ie9以上才支持
如果頁面的圖片很多的話, 從用戶訪問到onload觸發可能需要較長的時間, 互動效果就不能實作,必然影響用戶的體驗,此時用 DOMContentLoaded 事件比較合適,
2.2 調整視窗大小事件

window.onresize 是調整視窗大小加載事件, 當觸發時就呼叫的處理函式,
注意:
- 只要視窗大小發生像素變化,就會觸發這個事件,
- 我們經常利用這個事件完成回應式布局, window.innerWidth 當前螢屏的寬度
<!DOCTYPE html>
<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>
div {
width: 200px;
height: 200px;
background-color: pink;
}
</style>
</head>
<body>
<script>
window.addEventListener('load', function() {
var div = document.querySelector('div');
window.addEventListener('resize', function() {
console.log(window.innerWidth);
console.log('變化了');
if (window.innerWidth <= 800) {
div.style.display = 'none';
} else {
div.style.display = 'block';
}
})
})
</script>
<div></div>
</body>
</html>
3.1 兩種定時器
window 物件給我們提供了 2 個非常好用的方法-定時器,
setTimeout()
setInterval()
3.2 setTimeout() 定時器


<!DOCTYPE html>
<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>
</head>
<body>
<script>
// 1. setTimeout
// 語法規范: window.setTimeout(呼叫函式, 延時時間);
// 1. 這個window在呼叫的時候可以省略
// 2. 這個延時時間單位是毫秒 但是可以省略,如果省略默認的是0
// 3. 這個呼叫函式可以直接寫函式 還可以寫 函式名 還有一個寫法 '函式名()'
// 4. 頁面中可能有很多的定時器,我們經常給定時器加識別符號 (名字)
// setTimeout(function() {
// console.log('時間到了');
// }, 2000);
function callback() {
console.log('爆炸了');
}
var timer1 = setTimeout(callback, 3000);
var timer2 = setTimeout(callback, 5000);
// setTimeout('callback()', 3000); // 我們不提倡這個寫法
</script>
</body>
</html>
案例: 5秒后自動關閉的廣告
核心思路:5秒之后,就把這個廣告隱藏起來
用定時器setTimeout
<!DOCTYPE html>
<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>
</head>
<body>
<img src="images/ad.jpg" alt="" class="ad">
<script>
var ad = document.querySelector('.ad');
setTimeout(function() {
ad.style.display = 'none';
}, 5000);
</script>
</body>
</html>
3.3 停止 setTimeout() 定時器
clearTimeout()方法取消了先前通過呼叫 setTimeout() 建立的定時器,
注意:
- window 可以省略,
- 里面的引數就是定時器的識別符號 ,
<!DOCTYPE html>
<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>
</head>
<body>
<button>點擊停止定時器</button>
<script>
var btn = document.querySelector('button');
var timer = setTimeout(function() {
console.log('爆炸了');
}, 5000);
btn.addEventListener('click', function() {
clearTimeout(timer);
})
</script>
</body>
</html>
3.4 setInterval() 定時器

// 1. setInterval
// 語法規范: window.setInterval(呼叫函式, 延時時間);
setInterval(function() {
console.log('繼續輸出');
}, 1000);
// 2. setTimeout 延時時間到了,就去呼叫這個回呼函式,只呼叫一次 就結束了這個定時器
// 3. setInterval 每隔這個延時時間,就去呼叫這個回呼函式,會呼叫很多次,重復呼叫這個函式
</script>
案例: 倒計時

這個倒計時是不斷變化的,因此需要定時器來自動變化(setInterval)
三個黑色盒子里面分別存放時分秒
三個黑色盒子利用innerHTML 放入計算的小時分鐘秒數
第一次執行也是間隔毫秒數,因此剛重繪頁面會有空白
最好采取封裝函式的方式, 這樣可以先呼叫一次這個函式,防止剛開始重繪頁面有空白問題
<!DOCTYPE html>
<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>
div {
margin: 200px;
}
span {
display: inline-block;
width: 40px;
height: 40px;
background-color: #333;
font-size: 20px;
color: #fff;
text-align: center;
line-height: 40px;
}
</style>
</head>
<body>
<div>
<span class="hour">1</span>
<span class="minute">2</span>
<span class="second">3</span>
</div>
<script>
// 1. 獲取元素
var hour = document.querySelector('.hour'); // 小時的黑色盒子
var minute = document.querySelector('.minute'); // 分鐘的黑色盒子
var second = document.querySelector('.second'); // 秒數的黑色盒子
var inputTime = +new Date('2021-8-14 18:00:00'); // 回傳的是用戶輸入時間總的毫秒數
countDown(); // 我們先呼叫一次這個函式,防止第一次重繪頁面有空白
// 2. 開啟定時器
setInterval(countDown, 1000);
function countDown() {
var nowTime = +new Date(); // 回傳的是當前時間總的毫秒數
var times = (inputTime - nowTime) / 1000; // times是剩余時間總的秒數
var h = parseInt(times / 60 / 60 % 24); //時
h = h < 10 ? '0' + h : h;
hour.innerHTML = h; // 把剩余的小時給 小時黑色盒子
var m = parseInt(times / 60 % 60); // 分
m = m < 10 ? '0' + m : m;
minute.innerHTML = m;
var s = parseInt(times % 60); // 當前的秒
s = s < 10 ? '0' + s : s;
second.innerHTML = s;
}
</script>
</body>
</html>
3.5 停止 setInterval() 定時器

<button class="begin">開啟定時器</button>
<button class="stop">停止定時器</button>
<script>
var begin = document.querySelector('.begin');
var stop = document.querySelector('.stop');
var timer = null; // 全域變數 null是一個空物件
begin.addEventListener('click', function() {
timer = setInterval(function() {
console.log('ni hao ma');
}, 1000);
})
stop.addEventListener('click', function() {
clearInterval(timer);
})
</script>
案例: 發送短信

按鈕點擊之后,會禁用 disabled 為true
同時按鈕里面的內容會變化, 注意 button 里面的內容通過 innerHTML修改
里面秒數是有變化的,因此需要用到定時器
定義一個變數,在定時器里面,不斷遞減
如果變數為0 說明到了時間,我們需要停止定時器,并且復原按鈕初始狀態,
手機號碼: <input type="number"> <button>發送</button>
<script>
// 按鈕點擊之后,會禁用 disabled 為true
// 同時按鈕里面的內容會變化, 注意 button 里面的內容通過 innerHTML修改
// 里面秒數是有變化的,因此需要用到定時器
// 定義一個變數,在定時器里面,不斷遞減
// 如果變數為0 說明到了時間,我們需要停止定時器,并且復原按鈕初始狀態
var btn = document.querySelector('button');
var time = 3; // 定義剩下的秒數
btn.addEventListener('click', function() {
btn.disabled = true;
var timer = setInterval(function() {
if (time == 0) {
// 清除定時器和復原按鈕
clearInterval(timer);
btn.disabled = false;
btn.innerHTML = '發送';
} else {
btn.innerHTML = '還剩下' + time + '秒';
time--;
}
}, 1000);
})
</script>
3.6 this
this的指向在函式定義的時候是確定不了的,只有函式執行的時候才能確定this到底指向誰,一般情況下this的最終指向的是那個呼叫它的物件
現階段,我們先了解一下幾個this指向
- 全域作用域或者普通函式中this指向全域物件window(注意定時器里面的this指向window)
- 方法呼叫中誰呼叫this指向誰
3.建構式中this指向建構式的實體
<button>點擊</button>
<script>
// this 指向問題 一般情況下this的最終指向的是那個呼叫它的物件
// 1. 全域作用域或者普通函式中this指向全域物件window( 注意定時器里面的this指向window)
console.log(this);
function fn() {
console.log(this);
}
window.fn();
window.setTimeout(function() {
console.log(this);
}, 1000);
// 2. 方法呼叫中誰呼叫this指向誰
var o = {
sayHi: function() {
console.log(this); // this指向的是 o 這個物件
}
}
o.sayHi();
var btn = document.querySelector('button');
// btn.onclick = function() {
// console.log(this); // this指向的是btn這個按鈕物件
// }
btn.addEventListener('click', function() {
console.log(this); // this指向的是btn這個按鈕物件
})
// 3. 建構式中this指向建構式的實體
function Fun() {
console.log(this); // this 指向的是fun 實體物件
}
var fun = new Fun();
</script>
4. JS 執行機制
4.1 JS 是單執行緒
JavaScript 語言的一大特點就是單執行緒,也就是說,同一個時間只能做一件事,這是因為 Javascript 這門腳本語言誕生的使命所致——JavaScript 是為處理頁面中用戶的互動,以及操作 DOM 而誕生的,比如我們對某個 DOM 元素進行添加和洗掉操作,不能同時進行, 應該先進行添加,之后再洗掉,
單執行緒就意味著,所有任務需要排隊,前一個任務結束,才會執行后一個任務,這樣所導致的問題是: 如果 JS 執行的時間過長,這樣就會造成頁面的渲染不連貫,導致頁面渲染加載阻塞的感覺,
4.2 同步和異步
為了解決這個問題,利用多核 CPU 的計算能力,HTML5 提出 Web Worker 標準,允許 JavaScript 腳本創建多個執行緒,于是,JS 中出現了同步和異步,
同步:
前一個任務結束后再執行后一個任務,程式的執行順序與任務的排列順序是一致的、同步的,比如做飯的同步做法:我們要燒水煮飯,等水開了(10分鐘之后),再去切菜,炒菜,
異步:
你在做一件事情時,因為這件事情會花費很長時間,在做這件事的同時,你還可以去處理其他事情,比如做飯的異步做法,我們在燒水的同時,利用這10分鐘,去切菜,炒菜,
他們的本質區別: 這條流水線上各個流程的執行順序不同,


- 先執行執行堆疊中的同步任務,
- 異步任務(回呼函式)放入任務佇列中,
- 一旦執行堆疊中的所有同步任務執行完畢,系統就會按次序讀取任務佇列中的異步任務,于是被讀取的異步任務結束等待狀態,進入執行堆疊,開始執行,


由于主執行緒不斷的重復獲得任務、執行任務、再獲取任務、再執行,所以這種機制被稱為事件回圈( event loop),
5.1 什么是 location 物件
window 物件給我們提供了一個 location 屬性用于獲取或設定表單的 URL,并且可以用于決議 URL , 因為這個屬性回傳的是一個物件,所以我們將這個屬性也稱為 location 物件,
統一資源定位符 (Uniform Resource Locator, URL) 是互聯網上標準資源的地址,互聯網上的每個檔案都有一個唯一的 URL,它包含的資訊指出檔案的位置以及瀏覽器應該怎么處理它,
URL 的一般語法格式為:
protocol://host[:port]/path/[?query]#fragment
http://www.itcast.cn/index.html?name=andy&age=18#link

物件的屬性

<button>點擊</button>
<div></div>
<script>
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.addEventListener('click', function() {
// console.log(location.href);
location.href = 'http://www.itcast.cn';
})
var timer = 5;
setInterval(function() {
if (timer == 0) {
location.href = 'http://www.itcast.cn';
} else {
div.innerHTML = '您將在' + timer + '秒鐘之后跳轉到首頁';
timer--;
}
}, 1000);
</script>
主要練習資料在不同頁面中的傳遞,
第一個登錄頁面,里面有提交表單, action 提交到 index.html頁面
第二個頁面,可以使用第一個頁面的引數,這樣實作了一個資料不同頁面之間的傳遞效果
第二個頁面之所以可以使用第一個頁面的資料,是利用了URL 里面的 location.search引數
在第二個頁面中,需要把這個引數提取,
第一步去掉? 利用 substr
第二步 利用=號分割 鍵 和 值 split(‘=‘)
第一個陣列就是鍵 第二個陣列就是值
<form action="index.html">
用戶名: <input type="text" name="uname">
<input type="submit" value="登錄">
</form>
<div></div>
<script>
console.log(location.search); // ?uname=andy
// 1.先去掉? substr('起始的位置',截取幾個字符);
var params = location.search.substr(1); // uname=andy
console.log(params);
// 2. 利用=把字串分割為陣列 split('=');
var arr = params.split('=');
console.log(arr); // ["uname", "ANDY"]
var div = document.querySelector('div');
// 3.把資料寫入div中
div.innerHTML = arr[1] + '歡迎您';
</script>

6. navigator 物件
navigator 物件包含有關瀏覽器的資訊,它有很多屬性,我們最常用的是 userAgent,該屬性可以回傳由客戶機發送服務器的 user-agent 頭部的值,
下面前端代碼可以判斷用戶那個終端打開頁面,實作跳轉
if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
window.location.href = “”; //手機
} else {
window.location.href = “”; //電腦
}
7. history 物件
window 物件給我們提供了一個 history 物件,與瀏覽器歷史記錄進行互動,該物件包含用戶(在瀏覽器視窗中)訪問過的 URL,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/293995.html
標籤:其他
