1.綁定事件的方法
- 0級事件處理程序
//方式一
div.onclick = function() {
console.log('a');
}
//方式二
<div style = "width: 100px; height: 100px;" onclick = "console.log('a')"></div>
//刪除事件綁定
div.onclick = null;
eg:只能執行一次的事件
div.onclick = function() {
console.log('a');
this.onclick = null;
}
兼容性非常好但是隻能綁定一個事件處理函數。
基本等同於寫在HTML行間
on的綁定方法叫句柄的方法
- DOM二級事件處理程序
obj.addEventListener(type, fn, false);
//type:要處理的事件名,不加“on”
//fn:處理的函數
//false:表示在冒泡階段處理事件 true表示在捕獲階段處理
obj.addEventListener(click, function() {
console.log('a');
}, false)
//刪除通過addEventListener添加的事件
//但是不適用於以匿名函數即函數體放在參數fn中的處理程序
div.removeEventListener(type, fn, false);
// fn:函數引用,不能是函數體
IE9以下不兼容,說明符合W3C標準
注意click和onclick的區別
函數體和函數引用
不能重複綁定一個函數
div.addEventListener(click, test, false);
div.addEventListener(click, test, false);
function test() {
console.log('a');
}
//雖然寫了兩個綁定事件程序,但綁定的函數是一個,
//因此點擊一次執行同一個test()函數(寫在事件綁定程序中的是函數引用)
obj.addEventListener(click, function() {
console.log('a');
}, false)
obj.addEventListener(click, function() {
console.log('a');
}, false)
//雖然寫在兩個綁定函數中的是同樣的函數體,
//但是是不同的函數引用,因此是不同的函數
//點擊一次執行兩個函數
- IE事件處理程序
//注意事件要加'on'
obj.attachEvent('on' + type, fn);
//刪除attachEvent添加的事件
obj.detachEvent('on' + type, fn);
IE獨有,一個事件同樣可以綁定多個處理程序
一定要考慮循環添加事件時出現的閉包。
2.事件處理函數的運行環境
- 0級事件處理程序
程序this指向是DOM元素elem本身 - 2級事件處理程序
程序this指向是DOM元素elem本身 - IE特有事件處理程序
程序this指向window
//將事件this指向執行函數的方法
div.attachEvent('onclick', function() {
// 改變this指向
handle.call(div);
});
//事件處理函數
function handle() {
}
3.事件處理模型
- 事件冒泡
結構上(非視覺上)嵌套關係的元素,會存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上) - 事件捕獲
結構上(非視覺上)嵌套關係的元素,會存在事件捕獲的功能,即同一事件,自父元素捕獲向子元素。(自底向上)
IE沒有捕獲事件
被點擊的子元素的父元素是捕獲,被點擊的子元素叫事件執行
- 觸發順序:先捕獲,後冒泡
<div class = "wrapper">
<div class = "content">
<div class = "box">
</div>
</div>
</div>
//冒泡事件程序
wrapper.addEventListener('click', function() {
console.log('wrapperBubble');
}, false)
content.addEventListener('click', function() {
console.log('contentBubble');
}, false)
box.addEventListener('click', function() {
console.log('boxBubble');
}, false)
//捕獲事件程序
wrapper.addEventListener('click', function() {
console.log('wrapper');
}, true)
content.addEventListener('click', function() {
console.log('content');
}, true)
box.addEventListener('click', function() {
console.log('box');
}, true)
//點擊最內子元素box,輸出
wrapper
content
boxBubble
box
contentBubble
wrapperBubble
//因爲捕獲到最內子元素box時,相當於直接點擊最內子元素
//因此按照事件綁定的順序執行box上的兩個事件處理程序
事件執行的順序
- focus、blur、change、submit、reset、select等事件不冒泡
- IE特有的一種事件獲取方法
用於處理鼠標拖拽容易出元素後無法繼續作用的情況,比如鼠標幀頻比捕獲幀頻快時
div.setCapture();
這個div會獲取頁面上所有發生的事件,並捕獲到自己身上。
div.releaseCapture();
取消這個事件。
4.阻止事件冒泡
(1)取消冒泡
- W3C標準的
event.stopPropagation();
不支持IE9以下版本 - IE獨有
event.cancelBubble = true;
- 封裝取消冒泡的函數stopBubble(event)
function stopBubble(event) {
if(event.stopPropagation) {
event.stopPropagation;
} else {
event.cancelBubble = true;
}
}
(2)阻止默認事件
- 默認事件——表單提交、a標籤跳轉、右鍵菜單等
return false;
以對象屬性的方式註冊的事件(即DOM 0級事件)才生效
div.onclick = function() {
console.log('a');
return false;
}
event.preventDefault();
W3C標註,IE9以下不兼容
div.onclick = function(e) {
console.log('a');
e.preventDefault();
}
event.returnValue = false;
兼容IE
div.onclick = function(e) {
console.log('a');
e.returnValue = false;
}
- 封裝阻止默認事件的函數
cancelHandler(event);
function canckeHandler(event) {
if(e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
// 不能用 return false;
}
- 取消標籤默認事件
//相當於返回false
<a href = "javascript:void()"></a>
5.事件對象
e
返回事件對象,IE中 window.event
返回事件對象
div.onclick = function(e) {
event = e || window.event;
}
事件源對象
event.target
:火狐只有這個
event.srcElement
:IE只有這個
這倆Chrome都有
div.onclick = function(e) {
event = e || window.event;
traget = event.target || event.srcElement;
}
事件委託
利用事件冒泡的性質,將所有子元素都有的事件寫在父元素上,這樣點擊子元素冒泡到父元素執行事件處理,這就叫將子元素的事件委託爲父元素執行。
//將<li>的事件委託給<ul>
ul.onclick = function(e) {
var event = e || window.event;
var target = event.target || event.srcElement;
//再利用事件源對象 target 處理
console.log(target.innerText);
}
- 性能好,不需要循環所有的元素一個個綁定事件
- 靈活,當有新的子元素時不需要重新綁定事件
6.事件類型
鼠標事件
click、mousedown、mousemove、mouseup、contextmenu、
- click = mousedown + mouseup
觸發順序:先down然後up 最後click - contextmenu:右鍵菜單觸發事件
- onmouseover:當鼠標放到元素上時觸發
HTML5新規範:onmouseenter
- onmouseout:鼠標離開元素時
HTML5新規範:onmouseleave
- 用
e.button
區分鼠標的按鍵
document.onmousedown = function(e) {
// 觸發右鍵
if(e.button == 2) {
console.log('right');
} else if(e.button == 0) {
//觸發左鍵
console.log('left');
}
}
e.button = 2
DOM3標準規定:click事件只能監聽左鍵,只能通過mousedowm和mouseup來判斷鼠標鍵。
- 解決click和mouse事件的衝突
因爲每次mousedown和mouseup事件被觸發後click事件也會被觸發。
var firstTime = 0;
var lastTime = 0;
var key = false;
document.onmousedown = function() {
firstTime = new Date().getTime();
}
document.onmouseup = function() {
lastTime = new Date().getTime();
if(lastTime - firstTime < 300) {
key = true;
}
}
document.onclick = function() {
if(key) {
console.log("click");
key = false;
}
}
移動端事件
touchstart touchmove touchend
鍵盤事件
- onkeypress 不等於 onkeydown + onkeyup
onkeypress:鍵盤按壓下去後一直觸發
onkeydown:緊跟着onkeypress之後
onkeyup:鍵盤擡起來觸發 - keydown和keypress的區別
(1)keydown可以響應任意鍵盤按鍵(除了F類按鍵),keypress只可以響應字符類按鍵
e.which
檢測鍵盤的鍵值,鍵值不是按ASC||碼排列
(2)keypress返回ASC||碼,可以轉換成相應字符
keydown的e.charCode
一直爲0;
keypress的e.charCode
爲對應字符類按鍵的ASC||碼。
文本類操作
input.onput:只要輸入到框中的內容改變就會觸發事件;
input.change:根據聚焦與失去焦點後文本內容是否改變觸發事件。
#424242是互聯網標準黑色字體,比#000000淺一點。
IE6沒有position:fixed
窗體事件
- window.onload
- scroll