深入理解JS的事件绑定、事件流模型


Posted in Javascript onMay 13, 2018

 一、JS事件

(一)JS事件分类

1.鼠标事件:

click/dbclick/mouseover/mouseout

2.HTML事件:

 onload/onunload/onsubmit/onresize/onchange/onfoucs/onscroll

3.键盘事件:

 keydown:键盘按下时触发
 keypress:键盘按下并抬起的瞬间触发。
 keyup:键盘抬起触发

[注意事项]

①执行顺序:keydown keypress keyup
②keypress只能捕获数字,字母,符号键,而不能捕获功能键。
③长按时循环执行keydown--keypress
④有keydown,并不一定有keyup,当长按时焦点失去,将不再触发keyup
⑤keypress区分大小写,keydown,kewup不区分。

4.事件因子:

当触发一个事件时,该事件将向事件所调用的函数中,默认传入一个参数,

这个参数就是一个事件因子,包含了该事件的各种详细信息。

document.onkeydown=function(e){
 console.log(e);
 }
document.onkeydown=function(){
console.log(window.event);
}
//兼容浏览器的写法:
document.onkeydown=function(e){
e==e||Window.event;
var Code=e.keyCode||e.which||e.charCode;
if(code==13){
//回车
}
}

5.如何确定键盘按键?

①再出发的函数中,接收事件因子e。
②可以使用e.key直接去到按下的按键字符(不推荐使用)。
③一次可以使用keyCode/which/charCode取到按键的ASCII码值。

(兼容各种浏览器的写法)

var Code=e.keyCode||e.which||e.charCode;

//判断组合键
var isAlt=0,isEnt=0;
document.onkeyup=function(e){
if(e.keyCode==18){
isAlt=1;
}      
if(e.keyCode==13){
isEnt=1;
}    
if(isAlt==1&&isEnt==1){
alert("同时按下Alt和Enter键");
}
}

document.onkeyup=function(){
console.log("keyup");
}
document.onkeypress=function(){
console.log("keypress");
}
document.onkeydown=function(){
console.log("keydown");
}
document.onkeypress=function(){
console.log(window.event);
}
//判断是否按下了回车键
document.onkeydown=function(e){
var code=e.keyCode;
if(code==13){
alert("你输入的是回车键");
}
}

二、事件绑定模型

(一)DOM0事件模型

绑定注意事项:

①使用window.onload加载完成后进行绑定。

window.onload =function(){//事件}

②放在body后面进行绑定。

//body内容
<body>
  <button onclick="func()">内联模型绑定</button>
  <button id="btn1">哈哈哈哈</button>
  <button id="btn2">DOM2模型绑定</button>
  <button id="btn3">取消DOM2</button>
</body>

1.内联模型(行内绑定):将函数名直接作为html标签中属性的属性值。

<button onclick="func()">内联模型绑定</button>

 缺点:不符合w3c中关于内容与 行为分离的基本规范。

2.脚本模型(动态绑定):通过在JS中选中某个节点,然后给节点添加onclick属性。

document.getElementById("btn1")=function(){}

 优点:符合w3c中关于内容与行为分离的基本规范,实现html与js的分离。
 缺点:同一个节点只能添加一次同类型事件,如果添加多次,最后一个生效。

document.getElementById("btn1").onclick=function(){
  alert(1234);  
}
document.getElementById("btn1").onclick=function(){
  alert(234);  
}//重复的只能出现最近的一次

3.DOM0共有缺点:通过DOM0绑定的事件,一旦绑定将无法取消。

document.getElementById("btn3").onclick=function(){//不能取消匿名函数
  if(btn.detachEvent){
    btn.detachEvent("onclick",func1);
  }else{
    btn.removeEventListener("click",func1);
  }
    alert("取消DOM2");
}

(二)DOM2事件模型

1.添加DOM2事件绑定:

 ①IE8之前,使用.attachEvent("onclick",函数);
 ②IE8之后,使用.addEventListener("click",函数,true/false);
 参数三:false(默认)表示事件冒泡,传入true表示事件捕获。
 ③兼容所有浏览器的处理方式:

var btn=document.getElementById("btn1");
 if(btn.attachEvent){
 btn.attachEvent("onclick",func1);//事件,事件需要执行的函数IE8可以
 }else{
 btn.attachEventListener("click",func1);
 }

2.DOM2绑定的优点:

 ①同一个节点,可以使用DOM2绑定多个同类型事件。
 ②使用DOM2绑定的事件,可以有专门的函数进行取消。
3.取消事件绑定:
 ①使用attachEvent绑定,要用detachevent取消。
 ②使用attachEventListener绑定,要用removeEventListenter取消。
 注意:如果DOM2绑定的事件,需要取消,则绑定事件时,回调函数必须是函数名,
 而不能是匿名函数,因为取消事件时,取消传入函数名进行取消。

三、JS事件流模型

(一)JS中的事件流模型

1. 事件冒泡(fasle/不写):当触发一个节点的事件是,会从当前节点开始,依次触发其祖先节点的同类型事件,直到DOM根节点。
2. 事件捕获(true):当初发一个节点的事件时,会从DOM根节点开始,依次触发其祖先节点的同类型事件,直到当前节点自身。
3. 什么时候事件冒泡?什么时候事件捕获?
 ① 当使用addEventListener绑定事件,第三个参数传为true时表示事件捕获;
 ② 除此之外的所有事件绑定均为事件冒泡。

4. 阻止事件冒泡:

 ① IE10之前,e.cancelBubble = true;
 ② IE10之后,e.stopPropagation();

5. 阻止默认事件:

 ① IE10之前:e.returnValue = false;
 ② IE10之后:e.preventDefault();

//css
#div1{
  width: 300px;;
  height: 300px;
  background-color: powderblue;
}
#div2{
  width: 200px;
  height: 200px;
  background-color: deeppink;
}
#div3{
  width: 100px;
  height: 100px;
  background-color:#A9A9A9;
}

//html
<div id="div1">
  <div id="div2">
    <div id="div3"></div>
  </div>
</div>
<a href="01-事件笔记.html" rel="external nofollow" onclick="func()">超链接</a>
div1.addEventListener("click",function(){
  console.log("div1 click");
},false);
div2.addEventListener("click",function(){
  console.log("div2 click");
},false);
div3.addEventListener("click",function(){ //原来的顺序是:3-->2-->1。
//  myParagraphEventHandler(); //截获事件流后,只触发3.但是从2开始依然会冒泡;
  console.log("div3 click");
},false);

结果(事件冒泡)(由小到大div3-》div2-》div1):

深入理解JS的事件绑定、事件流模型

div1.addEventListener("click",function(){
  console.log("div1 click");
},true);
div2.addEventListener("click",function(){
  console.log("div2 click");
},true);
div3.addEventListener("click",function(){ 
//  myParagraphEventHandler(); //截获事件流后,只触发3.但是从2开始依然会冒泡;
  console.log("div3 click");
},true);

结果(事件捕获)(由小到大div3-》div2-》div1):

深入理解JS的事件绑定、事件流模型

//依然遵循事件冒泡
document.onclick=function(){
  console.log("document click")
}
//截获事件流阻止事件冒泡
function myParagraphEventHandler(e) {
   e = e || window.event;
  if (e.stopPropagation) {
     e.stopPropagation(); //IE10以后 
  } else {
     e.cancelBubble = true; //IE10之前
   }
}
//截获事件流阻止事件冒泡
function myParagraphEventHandler(e) {
   e = e || window.event;
  if (e.stopPropagation) {
     e.stopPropagation(); //IE10以后 
  } else {
     e.cancelBubble = true; //IE10之前
   }
}
//阻止默认事件
function eventHandler(e) {
  e = e || window.event;
// 防止默认行为 
   if (e.preventDefault) {
     e.preventDefault(); //IE10之后
  } else {
     e.returnValue = false; //IE10之前  
  }
}

总结

以上所述是小编给大家介绍的JS的事件绑定、事件流模型,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
Javascript Function对象扩展之延时执行函数
Jul 06 Javascript
js 自定义个性下拉选择框示例
Aug 20 Javascript
IE浏览器IFrame对象内存不释放问题解决方法
Aug 22 Javascript
关于编写性能高效的javascript事件的技术
Nov 28 Javascript
如何给ss bash 写一个 WEB 端查看流量的页面
Mar 23 Javascript
详解vue前后台数据交互vue-resource文档
Jul 19 Javascript
Angular.js前台传list数组由后台spring MVC接收数组示例代码
Jul 31 Javascript
微信小程序自定义tab实现多层tab嵌套功能
Jun 15 Javascript
JavaScript中set与get方法用法示例
Aug 15 Javascript
移动端吸顶fixbar的解决方案详解
Jul 17 Javascript
详细分析Node.js 多进程
Jun 22 Javascript
js属性对象的hasOwnProperty方法的使用
Feb 05 Javascript
在ES5与ES6环境下处理函数默认参数的实现方法
May 13 #Javascript
vue中的$emit 与$on父子组件与兄弟组件的之间通信方式
May 13 #Javascript
node 命令方式启动修改端口的方法
May 12 #Javascript
安装Node.js并启动本地服务的操作教程
May 12 #Javascript
Node.js中,在cmd界面,进入退出Node.js运行环境的方法
May 12 #Javascript
Vue拖拽组件开发实例详解
May 11 #Javascript
node前端模板引擎Jade之标签的基本写法
May 11 #Javascript
You might like
修改了一个很不错的php验证码(支持中文)
2007/02/14 PHP
微信支付扫码支付php版
2016/07/22 PHP
PHP实现超简单的SSL加密解密、验证及签名的方法示例
2017/08/28 PHP
PHP封装的mysqli数据库操作类示例
2019/02/16 PHP
php高性能日志系统 seaslog 的安装与使用方法分析
2020/02/29 PHP
仿中关村在线首页弹出式广告插件(jQuery版)
2012/05/03 Javascript
JavaScript 中的日期和时间及表示标准介绍
2013/08/21 Javascript
js 获取浏览器版本以此来调整CSS的样式
2014/06/03 Javascript
jQuery中trigger()方法用法实例
2015/01/19 Javascript
Vue中使用vux的配置详解
2017/05/05 Javascript
vue-router路由参数刷新消失的问题解决方法
2017/06/17 Javascript
JS中利用FileReader实现上传图片前本地预览功能
2018/03/02 Javascript
Express的HTTP重定向到HTTPS的方法
2018/06/06 Javascript
clipboard.js在移动端复制失败的解决方法
2018/06/13 Javascript
vue this.reload 方法 配置
2018/09/12 Javascript
微信小程序在地图选择地址并返回经纬度简单示例
2018/12/03 Javascript
JavaScript实现连连看连线算法
2019/01/05 Javascript
layui默认选中table的CheckBox复选框方法
2019/09/19 Javascript
分享JS表单验证源码(带错误提示及密码等级)
2020/01/05 Javascript
使用 Vue-TCB 快速在 Vue 应用中接入云开发的方法
2020/02/10 Javascript
JavaScript代码异常监控实现过程详解
2020/02/17 Javascript
解决vue 退出动画无效的问题
2020/08/09 Javascript
[02:41]2015国际邀请赛中国区预选赛观战指南
2015/05/20 DOTA
python的继承知识点总结
2018/12/10 Python
python 列表中[ ]中冒号‘:’的作用
2019/04/30 Python
详解Pycharm出现out of memory的终极解决方法
2020/03/03 Python
CSS3 media queries + jQuery实现响应式导航
2016/09/30 HTML / CSS
八一建军节部队活动方案
2014/02/04 职场文书
电台实习生求职信
2014/02/25 职场文书
高考备战决心书
2014/03/11 职场文书
公司优秀员工获奖感言
2014/08/14 职场文书
基层党组织整改方案
2014/10/25 职场文书
党员作风建设整改方案
2014/10/27 职场文书
期末复习计划
2015/01/19 职场文书
2016北大自主招生自荐信模板
2016/01/28 职场文书
SQL Server表分区删除详情
2021/10/16 SQL Server