事件的冒泡捕获阻止默认代理

事件的认识

<!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,但是有时候会有区别的。
timeStamp: 14919.125000000002
toElement: button#btn
type: "click"
view: Window
which: 1
x: 37
y: 21
__proto__: MouseEvent

removeEventListener解绑事件的,其中第二个参数也就是函数不能是匿名函数,否则解绑不了的,同理于addEventListener。

IE兼容

IE有:

  • attachEvent添加
  • detachEvent删除
    全都默认冒泡模式,两个参数,而且事件是'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 href="http://baidu.com">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>
//点击元素出现文本信息,只是选择了box1,box2没有选择。
用$$,反而点击两个都没有输出文本,为什么?
在控制台:
$$('.box')
(2) [div.box, div.box]    //选中了,是个NodeList类数组对象
$$('.box').onclick
undefined                  //没有onclick这个事件!事件只能一个一个去绑定。

如图

这里没有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还是形参,事件发生时才会有意义有值,也就是点击的瞬间,其他时候,是会报错的,没有值的。

再深一步: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>
可正常跟进子元素的变化,同步绑定事件了。没有绑定事件,但是都会向父元素冒泡,父元素绑定了事件啊

事件代理很好,不需要重新绑定事件了,尤其是懒加载啊,或者是子元素会发生变化啊。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容