事件的認識
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<button id="btn">click me</button>
<script>
var btn= document.querySelector('#btn')
btn.onclick = function(e){
console.log(e)
} //e代表綁定的事件對象摩疑,運行可得到藐鹤,是形參而已坞靶。
</script>
</body>
</html>
//得到事件——對象 MouseEvent {isTrusted: true, screenX: 594, screenY: 87, clientX: 37, clientY: 21…}
altKey: false //點時沒有按alt鍵
bubbles: true //冒泡的
button: 0
buttons: 0
cancelBubble: false
cancelable: true
clientX: 37 //位置
clientY: 21 //位置
composed: true
ctrlKey: false
currentTarget: null
defaultPrevented: false
detail: 1
eventPhase: 0
fromElement: null
isTrusted: true
layerX: 37
layerY: 21
metaKey: false
movementX: 0
movementY: 0
offsetX: 28 //點擊時鼠標 相對于元素本身的偏移
offsetY: 9 //點擊時相對于元素本身的偏移
pageX: 37
pageY: 21
path: Array(5)relatedTarget: null
returnValue: true
screenX: 594
screenY: 87
shiftKey: false
sourceCapabilities: InputDeviceCapabilities
srcElement: button#btn
target: button#btn //通過e.target看看點的是誰识补,等同于this和btn,但是有時候會有區(qū)別的酪穿。
timeStamp: 14919.125000000002
toElement: button#btn
type: "click"
view: Window
which: 1
x: 37
y: 21
__proto__: MouseEvent
removeEventListener解綁事件的凳干,其中第二個參數(shù)也就是函數(shù)不能是匿名函數(shù),否則解綁不了的昆稿,同理于addEventListener纺座。
IE兼容
IE有:
- attachEvent添加
- detachEvent刪除
全都默認冒泡模式,兩個參數(shù)溉潭,而且事件是'onclick',對比于addEventListener的'click'净响。這時候少欺,this不是綁定的元素了,而是window對象馋贤。
事件對象
剛開始的例子已經得到了事件的對象了赞别,這里比較重要的幾個拿出來說說:
- target 事件的目標元素
- stopPropagation() 取消事件的進一步捕獲或者冒泡,就是中斷配乓。
- preventDefault() 取消事件的默認行為:a鏈接點擊跳轉仿滔;form表單里的按鈕type=submit,點擊就會提交犹芹,崎页,,先不讓它們跳轉腰埂,提交飒焦,先做一些事情,然后才完成默認的屿笼。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style>
.container,
.box,
.target{
border:1px solid;
padding:20px;
}
</style>
</head>
<body>
<button id="btn">click me</button>
<div class="container">
container
<div class="box">
box
<div class="target">
target
</div>
</div>
</div>
<script>
var btn= document.querySelector('#btn')
btn.onclick = function(e){
console.log(e)
}
document.querySelector('.container').addEventListener('click',function(e){
console.log('container click..in捕獲')
},true)
document.querySelector('.box').addEventListener('click',function(e){
console.log('box click..in捕獲')
},true)
document.querySelector('.target').addEventListener('click',function(e){
console.log('target click..in捕獲')
},true)
document.querySelector('.container').addEventListener('click',function(e){
console.log('container click..in冒泡')
},false)
document.querySelector('.box').addEventListener('click',function(e){
// e.stopPropagation()
console.log('box click..in冒泡')
},false)
document.querySelector('.target').addEventListener('click',function(e){
console.log('target click..in冒泡')
},false)
</script>
</body>
</html>
//"container click..in捕獲"
"box click..in捕獲"
"target click..in捕獲"
"target click..in冒泡"
"box click..in冒泡"
"container click..in冒泡"
//在box中加入stopPropagation()然后牺荠,,驴一,
"container click..in捕獲"
"box click..in捕獲"
"target click..in捕獲"
"target click..in冒泡"
"box click..in冒泡"
stopPropagation()會阻止事件向后傳遞休雌,向后而已,當下沒事肝断。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<a >baidu</a>
<script>
document.querySelector('a').onclick =
function(e){
e.preventDefault() //先不跳轉
console.log(this.href)
if(/baidu.com/.test(this.href)){ //是否包含baidu.com
location.href = this.href //跳轉
}
}
</script>
</body>
</html>
老的IE里的事件獲取
用window.event獲取杈曲,比較奇葩。
常見事件
- load
- unload
- select
- changge
- submit
- resize
- scroll
- focus
- blur
事件代理
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<div class="box">box1</div>
<div class="box">box2</div>
</div>
<script>
function $(selector){
return document.querySelector(selector)
}
function $$(selector){
return document.querySelectorAll(selector)
}
$('.box').onclick = function(){
console.log(this.innerText)
}
//$$('.box').onclick = function(){
// console.log(this.innerText)
//} //先不用
</script>
</body>
</html>
//點擊元素出現(xiàn)文本信息孝情,只是選擇了box1,box2沒有選擇鱼蝉。
用$$洒嗤,反而點擊兩個都沒有輸出文本箫荡,為什么?
在控制臺:
$$('.box')
(2) [div.box, div.box] //選中了渔隶,是個NodeList類數(shù)組對象
$$('.box').onclick
undefined //沒有onclick這個事件羔挡!事件只能一個一個去綁定。
如圖![](http://ww1.sinaimg.cn/large/e3185026gy1fjkbwnitblj20m10fm40e.jpg)
這里沒有addEventListener和onclick的间唉,不過有forEach绞灼。
$$('.box').forEach(function(node){
node.onclick=function(){
console.log(node.innerText)
}
})
//就可以了,先遍歷呈野,然后再寫低矮。
比較麻煩,能不能綁定在父元素上被冒?
$('.container').onclick=function(e){
if(e.target.classList.contains('box')){
console.log(e.target.innerText)
}
} //e還是形參军掂,事件發(fā)生時才會有意義有值轮蜕,也就是點擊的瞬間,其他時候蝗锥,是會報錯的跃洛,沒有值的。
再深一步:forEach不一定是萬能的终议,汇竭,,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<div class="box">box1</div>
<div class="box">box2</div>
</div>
<button id="add">add</button>
<script>
function $(selector){
return document.querySelector(selector)
}
function $$(selector){
return document.querySelectorAll(selector)
}
$$('.box').onclick = function(){
console.log(this.innerText)
}
$$('.box').forEach(function(node){
node.onclick=function(){
console.log(node.innerText)
}
})
var i =3
$('#add').onclick=function(){
var box =document.createElement('div')
box.classList.add('box')
box.innerText = 'box' +(i++)
$('.container').appendChild(box)
}
</script>
</body>
</html>
//這時候add是可以正常輸出bix3,box4,box5,,,,,,,
但是控制臺輸出的innerText就還是原來是box1,box2,沒有后來增加的了穴张。
因為forEach一開始只給原本就有的做了遍歷细燎,都綁定了事件,后面新增的對象沒有綁定啊皂甘。
代理模式下呢:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="container">
<div class="box">box1</div>
<div class="box">box2</div>
</div>
<button id="add">add</button>
<script>
function $(selector){
return document.querySelector(selector)
}
function $$(selector){
return document.querySelectorAll(selector)
}
$$('.box').onclick = function(){
console.log(this.innerText)
}
$('.container').onclick=function(e){
if(e.target.classList.contains('box')){
console.log(e.target.innerText)
}
} //代理模式
var i =3
$('#add').onclick=function(){
var box =document.createElement('div')
box.classList.add('box')
box.innerText = 'box' +(i++)
$('.container').appendChild(box)
}
</script>
</body>
</html>
可正常跟進子元素的變化找颓,同步綁定事件了。沒有綁定事件叮贩,但是都會向父元素冒泡击狮,父元素綁定了事件啊
事件代理很好,不需要重新綁定事件了益老,尤其是懶加載啊彪蓬,或者是子元素會發(fā)生變化啊。