#hello,JS:10 -01事件(流)和事件处理程序

前言:

最近,很多事情的时间交叉点汇集到一起,时间明显越来越少了。因为要学做项目了,写博客的记录已经赶不上课程的学习进度,记录知识在博客真的是一个耗费时间和精力的事情啊,这其中还要查资料、弄懂知识点,而且也到了再一次梳理知识集中问老师的时候。赶着时间学习,会有一种赶着你跑的冲劲,加油吧。

一、事件

dom操作,可以用JS在页面上操作元素。不过dom操作需要一个时机,即跟用户交互时,什么时候才能改变这个dom结构,那么此时就用到了事件。
用户在浏览器上的任何操作,都可能触发一个事件,如鼠标移动。滚动页面、点击、甚至鼠标放在页面上的某处等任何的页面操作都会触发一个事件。

二、事件流

事件是如何产生和如何传播
假设事件不传播,无任何事件传播机制,点到什么是什么。那么,当我们点击整个页面的dom,事件却不传播,那页面中的某层结构怎么知道点击了该事件,那又如何去触发事件?

1、事件冒泡模型

元素先监听到这个事件,往外传播


image

2、事件捕获模型

document最先监听到这个事件


image

3、DOM事件流

先捕获,再冒泡


image

允许在某些地方监听事件,假设在某个元素两阶段都绑定一个事件监听器,看你是决定在左边捕获阶段监听,还是右边冒泡阶段监听,哪一边有响应,哪一边事件就被触发。即可以在任一阶段、任意时机监听事件

三、事件的使用方式

1、事件处理程序

也叫事件侦听器。当用户点击(或当某个事件触发的时候),我们所要做的事情。

2、如何绑定事件处理程序?

JavaScript指定事件处理程序
(1)对一个元素绑定一个事件函数:
语法:

<input id="btnClick" type="button" value="Click Here" />

<script type="text/javascript">
    var btnClick = document.getElementById('btnClick');//声明一个变量,选择这个元素给它做个赋值,选择这个dom元素
    btnClick.onclick = function showMessage() {   //元素.事件(),元素绑定一个事件,即onclick,该事件名可以改,如oniput、onfocus等(本身没有执行,只有当事件触触发,即用户交互时,才会被执行)
        alert(this.id);//this相当于btnClick这个元素,作为一个占位符存在
    };
</script>

函数什么时候执行?看此例子:http://js.jirengu.com/ponaz/2/edit

image

当用户点击触发事件时,就会将该事件的对应执行放进任务队列里,此时这个事件函数才会去被执行。由此可以明白两件事:

  • 绑定这个函数事件则是同步
  • 点击、执行函数事件的操作是异步

(2)对一个元素绑定多个事件函数
看下面这个例子:https://user-gold-cdn.xitu.io/2018/8/13/165314721529faef

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <button id="btn">click me</button>
</body>
</html>

<script>
var btn = document.querySelector('#btn')
//#事件01
btn.onclick = function(){
console.log(this)
console.log(this.innerText)
}
//#事件02
 btn.onclick = function(){
  console.log('hello world')
}
</script>

image

总结: 这个时候,添加了#02事件函数,并点击按钮click me,发事件函数,输出'hello world',直接覆盖#01事件函数的值。

DOM2事件处理程序(实现对一个元素绑定多个事件)
(1)dom作为事件处理的一个基本标准,dom2级事件为dom事件的升级。
(2)DOM2级事件定义用于处理指定和删除事件处理程序的操作:

  • addEventListener
  • removeEventListener
    (3)所有的DOM节点都包含这两个方法,并且它们都接受三个参数:
    A、事件类型
    B、事件处理方法
    C、布尔参数,如果是true表示在捕获阶段调用事件处理程序,如果是false,则是在事件冒泡阶段处理

(4)绑定事件方法实例演示:
addEventListener 绑定事件(直接执行一个函数)

<input id="btnClick" type="button" value="Click Here" />

<script type="text/javascript">
    var btnClick = document.getElementById('btnClick');
    btnClick.addEventListener('click', function() {
        alert(this.id);  //函数里的this代表当前的元素btnClick,所以我们可以通过this.id获取当前元素的id
    }, false);
</script>

例子:http://js.jirengu.com/lajoy/1/edit?js,console,output

image

总结:
这里并不是给变量添加一个值,而是通过执行addEventListener 这样一个函数,函数可以执行多次,对同样事件可以做多个绑定做不同的事情,也不会产生覆盖。

区别
1、JavaScript指定事件:btnClick.onclick =functionshowMessage(){alert(this.id);} 为属性添加一个值;DOM2事件处理程序:addEventListener 执行一个函数
2、JavaScript指定事件的事件是:onclick,DOM2事件处理程序的事件是:click
3、DOM2事件处理程序的dom节点最后还可以添加布尔值,表示处于冒泡阶段(false)还是捕获阶段(true)。默认情况下(无传进参数),为冒泡阶段(false)
4、this:alert(this.id) //函数里的this代表当前的元素btnClick,所以我们可以通过this.id获取当前元素的id
思考:
事件到底是什么?此时我们可以通过下面例子来说明事件的一些问题:
例子链接: http://js.jirengu.com/hahid/1/edit?html,js

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
    <button id="btn">click</button>
</body>
</html>

<script>
//简单的绑定事件,可通过此方法进行绑定
var btn = document.querySelector('#btn')
btn.onclick = function (e){
   console.log(e)
}
//通过这个函数可以用来查看这个事件。可以在里面传一个参数e
//或者采用另一种绑定事件的方法:
btn.addEventListener('click',function(e){
  console.log(e)
})
</script>

//注:e,只是一个自定义的参数,可以随意改变参数名

点击click时,在控制台上打印出事件,事件内都是一些对象(带有属性和值),可以从这堆属性中观察到一些重要的参考(只是部分例举),如:

altKey:false  //表示在点击事件的时候,没有点alt键
bubbles:true  //表示这个事件是冒泡
clientX:39
clientY:18   //表示它的一个位置
toElement:button#btn   //说明当前传递的元素

这里可以通过(e.target)看一看到底点击了哪个元素,并不是我们通常意义下看到的例子中的当前元素btn,现在一般来说,绑定一个事件可以使用以下几个方法(续上面的例子):

<script>
var btn = document.querySelector('#btn')
btn.addEventListener('click',function(e){
  console.log(this)
//或
   console.log(btn)
//或
  console.log(e.target)
})
</script>

(5)如何解绑事件(一般情况下不做)
removeEventListener 解绑事件
与addEventListener相对应,通过removeEventListener移除解绑事件,表现为点击时无反应
需要注意的是,removeEventListener解绑事件,不能使用匿名函数(无法获知要移除哪一个),正确如:

<script type="text/javascript">
    var btnClick = document.getElementById('btnClick');
    var handler=function() {
        alert(this.id);
    }
    btnClick.removeEventListener('click', handler, false);
</script>

(6)事件整体实例展示
A、冒泡阶段·实例展示

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
   <button id="btn">click me</button>
  
  <div class="container">
     container
    <div class="box">
        box
      <div class="target">
        hello
      </div>
    </div>
  </div>
</body>
</html>

<script>
//选中元素
var container = document.querySelector('.container')

var box = document.querySelector('.box')

var target = document.querySelector('.target')

//绑定事件
container.addEventListener('click', function(){
  console.log('container click...')
})

box.addEventListener('click', function(){
  console.log('box click...')
})

target.addEventListener('click',function(){
  console.log('target click...')
})

</script>

默认情况下(无传进的参数),事件绑定是呈现冒泡阶段,执行结果展示:


image

执行的过程事实上是,点击这个事件的时候,一开始便是从container——box——hello,返回时,为冒泡阶段,从hello——box——container,绑定了事件,分别有了响应控制台分别打印出:

"target click..."
"box click..."
"container click..."

这一过程就像是从下到上的冒泡过程,冒泡过程中到哪个事件元素,触发,响应,则会执行对应事件函数

B、事件捕获阶段·实例展示

//html同上

<script>
//选中元素
var container = document.querySelector('.container')

var box = document.querySelector('.box')

var target = document.querySelector('.target')

//绑定事件,添加了参数true
container.addEventListener('click', function(){
  console.log('container click...')
},true)

box.addEventListener('click', function(){
  console.log('box click...')
},true)

target.addEventListener('click',function(){
  console.log('target click...')
},true)
<script>
image

捕获阶段,点击事件hello,结果显示在刚进去的时候就绑定了事件,所以一开始事件元素就监听到,那么事件触发响应的过程就是hello——box——container,结果为:

"container click..."
"box click..."
"target click..."

C、事件传播整体机制原理和实践·实例展示

//html同上

<script>
//选中元素
var container = document.querySelector('.container')
var box = document.querySelector('.box')
var target = document.querySelector('.target')

//绑定事件
//捕获事件绑定
container.addEventListener('click', function(){
  console.log('container 捕获 click...')
},true)

box.addEventListener('click', function(){
  console.log('box 捕获 click...')
},true)

target.addEventListener('click',function(){
  console.log('target 捕获 click...')
},true)

//冒泡事件绑定
container.addEventListener('click', function(){
  console.log('container 冒泡 click...')
},false)

box.addEventListener('click', function(){
  console.log('box 冒泡 click...')
},false)

target.addEventListener('click',function(){
  console.log('target 冒泡 click...')
},false)
</script>

如图所示:结果输出,说明是先进行捕获事件触发、响应,再到冒泡事件触发、响应,先进后出:


image

【不常用】HTML内联方式——onclick ,当用户点击的时候的事件

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

推荐阅读更多精彩内容