基本概念
- 事件是一些特定動(dòng)作發(fā)生時(shí)所發(fā)出的信號(hào),JavaScript中的事件是可以被 JavaScript 偵測(cè)到的行為。
- 網(wǎng)頁中的每個(gè)元素都可以產(chǎn)生某些事件。比方說,我們可以在用戶點(diǎn)擊某按鈕時(shí)產(chǎn)生一個(gè) onClick 事件來觸發(fā)某個(gè)函數(shù)。
事件處理(添加事件)
- (HTML事件處理)內(nèi)聯(lián)方式添加事件將事件看做標(biāo)簽的一個(gè)屬性,與HTML混寫,代碼多時(shí)不容易管理
(DOM0級(jí)事件處理)腳本方式添加事件,實(shí)現(xiàn)了HTML和JS的分離
-
DOM2級(jí)事件處理
- ele.addEventListener()
- ele.removeEventListener()
- IE8及其以下需要使用IE事件處理程序attachEvent/detachEvent
var div1 = document.getElementById('div1'); var btn2 = document.getElementById('btn2'); var btn3 = document.getElementById('btn3'); function test1() { div1.innerHTML='點(diǎn)擊事件'; } function test2() { div1.style.background = 'rgb(52, 205, 112)'; } // DOM 0級(jí)事件處理 btn2.onclick = test2;// 不用謝() // DOM 2級(jí)事件處理 if (btn3.addEventListener) { btn3.addEventListener('click',test1); btn3.addEventListener('click',test2); btn3.removeEventListener('click',test2); }else if (btn3.attachEvent) { btn3.attachEvent('click',test1); btn3.attachEvent('click',test2); btn3.detachEvent('click',test2); }
常用的事件類型(事件處理函數(shù))
鼠標(biāo)事件
- onclick 鼠標(biāo)點(diǎn)擊某個(gè)對(duì)象
- ondblclick 當(dāng)用戶雙擊某個(gè)對(duì)象時(shí)調(diào)用的事件句柄。
ondblclick="test1()" - onmousedown 鼠標(biāo)按鈕被按下。
onmousedown="test1()" - onmousemove 鼠標(biāo)被移動(dòng)。
onmousemove="test1()" - onmouseout 鼠標(biāo)從某元素移開。
onmouseout="test1()" - onmouseover 鼠標(biāo)移到某元素之上。
addEventListener('mouseover',test1()) - onmouseup 鼠標(biāo)按鍵被松開。
onmouseup="test1()" - ......
btn3.detachEvent('click',
// 匿名函數(shù)
function () {
xxx
}
);
鍵盤事件
- onkeydown 某個(gè)鍵盤按鍵被按下。
- onkeyup 某個(gè)鍵盤按鍵被松開。
- onkeypress 某個(gè)鍵盤按鍵被按下并松開。
- onkeydown與onkeypress的區(qū)別
- 一個(gè)放開一個(gè)沒有放開,onkeydown 先于 onkeypress 發(fā)生。
- 我們沒敲擊一下鍵盤這三個(gè)事件會(huì)依次發(fā)生:onkeydown--onkeypress--onkeyup
- onkeypress 事件不是適用于系統(tǒng)按鈕(如: ALT, CTRL, SHIFT, ESC)。
- onkeydown 是在用戶按下任何鍵盤鍵時(shí)發(fā)生。 監(jiān)聽一個(gè)用戶是否按下按鍵請(qǐng)使用 onkeydown 事件,所有瀏覽器都支持 onkeydown 事件。
- 鍵盤事件的event對(duì)象中包含一個(gè)keyCode屬性,onkeydown和onkeyup表示你按下的具體的鍵,而onkeypress表示你按下的字符。
- ......
onkeydown="test1()"body中添加
其他事件
- onload 一個(gè)頁面或一幅圖像完成加載
- onunload 用戶退出頁面。
- IE6,IE7,IE8 中 刷新頁面、關(guān)閉瀏覽器之后、頁面跳轉(zhuǎn)之后都會(huì)執(zhí)行.
- IE9 刷新頁面 會(huì)執(zhí)行,頁面跳轉(zhuǎn)、關(guān)閉瀏覽器不能執(zhí)行;
- Opera、Chrome 任何情況都不執(zhí)行。
- onabort 圖像的加載被中斷
- onblur 元素失去焦點(diǎn)。
- onchange 域的內(nèi)容被改變。
- onerror 在加載文檔或圖像時(shí)發(fā)生錯(cuò)誤。
- onfocus 元素獲得焦點(diǎn)。
- onselect 文本被選中。
- onreset 重置按鈕被點(diǎn)擊。
- onscroll 當(dāng)文檔被滾動(dòng)時(shí)發(fā)生的事件。
- ......
或者放到body
// window.onload=function (){
// myFun4()
// }
事件的對(duì)象
在觸發(fā)某個(gè)事件時(shí),會(huì)產(chǎn)生一個(gè)事件對(duì)象event。這個(gè)對(duì)象中包含著所有與事件有關(guān)的信息。包括導(dǎo)致事件的元素,事件的類型以及其他與特定事件相關(guān)的信息。
- type:獲取事件類型
- target:獲取事件目標(biāo)
- clientX 返回當(dāng)事件被觸發(fā)時(shí),鼠標(biāo)指針的水平坐標(biāo)。
- clientY 返回當(dāng)事件被觸發(fā)時(shí),鼠標(biāo)指針的垂直坐標(biāo)。
- screenX 返回當(dāng)某個(gè)事件被觸發(fā)時(shí),鼠標(biāo)指針的水平坐標(biāo)。
- screenY 返回當(dāng)某個(gè)事件被觸發(fā)時(shí),鼠標(biāo)指針的垂直坐標(biāo)。
- ctrlKey 返回當(dāng)事件被觸發(fā)時(shí),"CTRL" 鍵是否被按下。
- altKey 返回當(dāng)事件被觸發(fā)時(shí),"ALT" 是否被按下。
- shiftKey 返回當(dāng)事件被觸發(fā)時(shí),"SHIFT" 鍵是否被按下。
- keyCode 事件屬性 keyCode 屬性在 Firefox 瀏覽器的 onkeypress 事件中是無效的。
- which 返回onkeypress事件觸發(fā)的鍵的值的字符代碼,或者 onkeydown 或 onkeyup 事件的鍵的代碼。
注意:IE8 及其更早版本不支持 which 屬性。不支持的瀏覽器可使用 keyCode 屬性。但是, keyCode 屬性在 Firefox 瀏覽器的 onkeypress 事件中是無效的。 var x = event.which || event.keyCode; // 使用 which 或 keyCode, 這樣可支持不同瀏覽器- button 返回當(dāng)事件被觸發(fā)時(shí),哪個(gè)鼠標(biāo)按鈕被點(diǎn)擊。
- button 事件屬性可返回一個(gè)整數(shù),指示當(dāng)事件被觸發(fā)時(shí)哪個(gè)鼠標(biāo)按鍵被點(diǎn)擊。event.button=0|1|2
- 0 1 2分別代表左中右三個(gè)鍵,但是再IE里左中右三個(gè)鍵對(duì)應(yīng)的數(shù)字為1 4 2
- ......
事件的冒泡和捕獲
- 事件的冒泡:事件按照從最特定的事件目標(biāo)到最不特定的事件目標(biāo)的順序觸發(fā)。
- 事件冒泡可以形象地比喻為把一顆石頭投入水中,泡泡會(huì)一直從水底冒出水面。也就是說,事件會(huì)從最內(nèi)層的元素開始發(fā)生,一直向上傳播,直到document對(duì)象。
- 事件的捕獲:與事件冒泡相反,事件會(huì)從最外層開始發(fā)生,直到最具體的元素。
- 事件捕獲時(shí),父級(jí)元素先觸發(fā),子級(jí)元素后觸發(fā)
- 可以自己選擇綁定事件時(shí)采用事件捕獲還是事件冒泡,方法就是綁定事件時(shí)通過addEventListener函數(shù),它有三個(gè)參數(shù),第三個(gè)參數(shù)若是true,則表示采用事件捕獲,若是false,則表示采用事件冒泡。
- IE9以前的版本只支持事件冒泡,不支持事件捕獲,它也不支持addEventListener函數(shù),不會(huì)用第三個(gè)參數(shù)來表示是冒泡還是捕獲,它提供了另一個(gè)函數(shù)attachEvent。
- 不是所有的事件都能冒泡,例如:blur、focus、load、unload
- stopPropagation():阻止事件冒泡
- preventDefault():阻止事件的默認(rèn)行為
事件的綁定
- ele.addEventListener()
- ele.removeEventListener()
// 循環(huán)變化顏色
<!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 type="text/css">
#div1{
margin: 15px auto;
background: orange;
width: 200px;
height: 200px;
border-radius: 200px;
}
</style>
</head>
<body>
<div id="div1"></div>
<script type="text/javascript">
var div1 = document.getElementById('div1');
div1.onclick=test1;
function test1() {
div1.style.background = 'rgb(41, 48, 173)';
setTimeout('test2()',500);
}
function test2() {
div1.style.background = 'rgb(173, 65, 41)';
setTimeout('test3()',500);
}
function test3() {
div1.style.background = 'rgb(43, 173, 41)';
setTimeout('test1()',500);
}
</script>
</body>
</html>
- scrollLeft:設(shè)置或獲取位于對(duì)象左邊界和窗口中目前可見內(nèi)容的最左端之間的距離
- scrollTop:設(shè)置或獲取位于對(duì)象最頂端和窗口中可見內(nèi)容的最頂端之間的距離
- scrollHeight: 獲取對(duì)象的滾動(dòng)高度。
- scrollWidth:獲取對(duì)象的滾動(dòng)寬度
- document.documentElement.scrollTop||document.body.scrollTop 垂直方向滾動(dòng)的值
<!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 type="text/css">
div{
margin: 15px auto;
background: orange;
width: 200px;
height: 200px;
padding: 15px;
border-radius: 200px;
position: absolute;
}
</style>
</head>
<body>
<script type="text/javascript">
function test1(e) {
var num = 20;
var divs = document.getElementsByTagName('div');
var body = document.getElementsByTagName('body')[0];
for (var i = 0; i < num; i++) {
var rad = Math.floor(Math.random()*10)+'px';
divs[i] = document.createElement('div');
divs[i].style.background='rgb('+4*i+','+2*i+','+i+')';
divs[i].style.width=divs[i].style.height=rad
divs[0].style.left=e.clientX+'px';
divs[0].style.top=e.clientY+'px';
divs[i].style.left=e.clientX+Math.floor(Math.random()*10*i)+'px';
divs[i].style.top=e.clientY+Math.floor(Math.random()*10*i)+'px';
body.appendChild(divs[i])
}
}
document.onmousedown=test1;
</script>
</body>
</html>
// 隨機(jī)鍵盤
<!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 type="text/css">
input{
width: 30px;
height: 30px;
border-radius: 20px;
margin: 2px;
outline: none;
}
.div{
width: 120px;
height: 150px;
padding: 10px;
text-align: center;
background: rgba(180,90,30,0.3);
border:2px solid orange;
}
.inp{
width: 130px;
height: 20px;
}
.clear,.new{
width: 60px;
font-size: 12px;
}
</style>
</head>
<body>
<input type="text" class="inp" id="txt"><br>
<input type="button" class="clear" value="清楚" onclick="clearnum()">
<input type="button" class="new" value="重置鍵盤" onclick="cz()">
<div id="div1" class="div"></div>
<script type="text/javascript">
var txt = document.getElementById('txt');
var div1 = document.getElementById('div1');
// 生成隨機(jī)數(shù)
function number() {
var num = [0,1,2,3,4,5,6,7,8,9];
var rand = [];
for (var i = 0; i < 10; i++) {
var n = Math.floor(Math.random()*(10-i));
rand.push(num[n]);
num.splice(n,1)// 刪除num數(shù)組中下標(biāo)為n的元素,保證不會(huì)出現(xiàn)重復(fù)數(shù)字
}
return rand;
}
document.write(number())
function createBtn() {
var ranArr = number();
var btnArr = [];
for (var i = 0; i < ranArr.length; i++) {
var btn = document.createElement('input');
btn.setAttribute('type','button');
btn.value = ranArr[i];
btn.onclick = btnClick;
btnArr.push(btn);
div1.appendChild(btn);
}
}
createBtn();
function btnClick() {
txt.value += this.value;// 這里this就是調(diào)用這個(gè)函數(shù)的對(duì)象
}
function clearnum() {
txt.value = '';
}
function cz() {
window.location.reload();
}
</script>
</body>
</html>
HTML5新增的JS選擇器
在傳統(tǒng)的 JavaScript 開發(fā)中,原生的 JavaScript 所提供的 DOM 選擇方法并不多,僅僅局限于通過 tag, name, id 等方式來查找,這顯然是遠(yuǎn)遠(yuǎn)不夠的,如果想要進(jìn)行更為精確的選擇不得不使用看起來非常繁瑣的正則表達(dá)式,或者使用某個(gè)庫。
querySelector 和 querySelectorAll 方法是 W3C Selectors API 規(guī)范中定義的。他們的作用是根據(jù) CSS 選擇器規(guī)范,便捷定位文檔中指定元素。 現(xiàn)在所有的瀏覽器廠商都提供了 querySelector 和 querySelectorAll 這兩個(gè)方法的支持,使用它們,你可以像使用 CSS 選擇器一樣快速地查找到你需要的節(jié)點(diǎn)。
HTML5新增的JS選擇器
querySelector 和 querySelectorAll 方法是 W3C Selectors API 規(guī)范中定義的。他們的作用是根據(jù) CSS 選擇器規(guī)范,便捷定位文檔中指定元素。功能類似于jQuery的選擇器。這使得在編寫原生JavaScript代碼時(shí)方便了許多。
- document.querySelector('selectors');
- 該方法返回滿足條件的單個(gè)元素。按照深度優(yōu)先和先序遍歷的原則使用參數(shù)提供的CSS選擇器在DOM進(jìn)行查找,返回第一個(gè)滿足條件的元素
-
document.querySelectorAll('selectors');
- 該方法返回所有滿足條件的元素,結(jié)果是個(gè)nodeList集合。查找規(guī)則與前面所述一樣。
-
注意事項(xiàng)
- 參數(shù)selectors 可以包含多個(gè)CSS選擇器,用逗號(hào)隔開:element = document.querySelector('selector1,selector2,...');br>elementList = document.querySelectorAll('selector1,selector2,...');
- 這種方法查找元素是非實(shí)時(shí)的,即不支持有動(dòng)態(tài)添加元素情況下的查找
-
document.getElementsByClassName("selector");返回文檔中所有指定類名的元素集合,作為 NodeList 對(duì)象。
- IE8以下的瀏覽器中,無法通過Class標(biāo)簽getElementsByClassName函數(shù)獲取元素。ie9以上及主流瀏覽器均支持通過Class獲取元素,ie8及以下的解決辦法:
- 可以用jQuery代替 引用jQuery后,使用$(".ClassName")等方法獲取元素。
- 自己寫getElementsByClassName函數(shù)方法
<script> //快捷的通過class ID 元素名稱查找元素 function myFun1(){ // document.querySelector("li").style.backgroundColor = "red"; // document.querySelector("#u2").style.backgroundColor = "blue"; document.querySelector(".bb").style.backgroundColor = "blue"; } //結(jié)合CSS3的選擇器進(jìn)行更精確的查找 function myFun2(){ document.querySelector("#u2>li+li").style.backgroundColor = "red"; document.querySelector("#u1 li p").style.backgroundColor = "red"; } //只匹配第一個(gè)符合條件的元素 function myFun3(){ document.querySelector("h2, h3").style.backgroundColor = "red"; } //querySelectorAll返回的是一個(gè)集合 function myFun4() { var x=document.querySelectorAll("li"); x[3].style.backgroundColor = "green" //alert(x.length) for (var i = 0; i < x.length; i++) { x[i].style.backgroundColor = "red"; } } function myFun5(){ var x=document.querySelectorAll("#u1 .bb") for (var i = 0; i < x.length; i++) { x[i].style.backgroundColor = "green"; } } //querySelectorAll查找元素不是實(shí)時(shí)的 function myFun6(){ var u1=document.getElementById('u1') // var arr=document.querySelectorAll("#u1>li") var arr=u1.getElementsByTagName('li') alert(arr.length) var newli=document.createElement('li') newli.innerHTML='newli' u1.appendChild(newli) alert(arr.length) } //通過className查找元素 function myFun7() { var x = document.getElementsByClassName("bb"); for (var i = 0; i < x.length; i++) { x[i].style.backgroundColor = "red"; } } </script>
瀏覽器兼容性
- 版本較低的瀏覽器有會(huì)存在兼容性問題。
- 很多框架中封裝了解決瀏覽器兼容性的問題的方法,比如JQ;使用合適的框架不但可以解決兼容性還可以節(jié)省很多時(shí)間,效率更高
- 在不用框架的情況下可以自己編寫一個(gè)解決兼容性的函數(shù),或者直接引用一個(gè)解決兼容問題的函數(shù)
- 相信隨著瀏覽器的更新和語言的規(guī)范這些目前的兼容性問題未來很可能就不存在了
理解全局對(duì)象Global
- 全局屬性和函數(shù)可用于所有內(nèi)建的 JavaScript 對(duì)象。全局對(duì)象是所有全局方法的擁有者,用來統(tǒng)一管理全局方法,全局方法也就是全局函數(shù)。
- parseInt() 函數(shù)可解析一個(gè)字符串,并返回一個(gè)整數(shù)。
- parseFloat() 解析一個(gè)字符串并返回一個(gè)浮點(diǎn)數(shù)。
- 注意:可以將數(shù)字開頭的字符串轉(zhuǎn)換成數(shù)值,但是不可以轉(zhuǎn)換非數(shù)字開頭的字符串
- 如果指定的字符串中包含非數(shù)字字符,只要字符串開頭的一部分符合整數(shù)的轉(zhuǎn)換規(guī)則,則parseInt()函數(shù)會(huì)將這一部分字符串轉(zhuǎn)化為整數(shù)(從字符串開頭,直到遇到非數(shù)字字符為止)。如果字符串以非數(shù)字字符開頭,則返回NaN。
- isNaN(x)函數(shù)用于檢查其參數(shù)是否是非數(shù)字值。NaN 即 Not a Number
- 可用于判斷其參數(shù)是否是 NaN,該值表示一個(gè)非法的數(shù)字
- 如果 x 是特殊的非數(shù)字值 NaN(或者能被轉(zhuǎn)換為這樣的值),返回的值就是 true。如果 x 是其他值,則返回 false。
- isNaN() 函數(shù)通常用于檢測(cè) parseFloat() 和 parseInt() 的結(jié)果,以判斷它們表示的是否是合法的數(shù)字。當(dāng)然也可以用 isNaN() 函數(shù)來檢測(cè)算數(shù)錯(cuò)誤,比如用 0 作除數(shù)的情況。
- ......
變量的作用范圍
- 作用域是指有效范圍,JS變量的作用域有全局和局部之分
- "全局變量":申明在函數(shù)之外的變量
- "局部變量":申明在函數(shù)體中的變量,并且只能在當(dāng)前函數(shù)體內(nèi)訪問
- 如果函數(shù)內(nèi)部有定義變量,即使在定義之前輸出但會(huì)先執(zhí)行后面定義語句,然后判斷輸出結(jié)果
- 全局變量的優(yōu)點(diǎn):可以減少變量的個(gè)數(shù),減少由于實(shí)際參數(shù)和形式參數(shù)的數(shù)據(jù)傳遞帶來的時(shí)間消耗。
- 全局變量缺點(diǎn):使函數(shù)的代碼可讀性降低。由于多個(gè)函數(shù)都可能使用全局變量,函數(shù)執(zhí)行時(shí)全局變量的值可能隨時(shí)發(fā)生變化,對(duì)于程序的查錯(cuò)和調(diào)試都非常不利。