javascript自定义事件功能与用法实例分析


Posted in Javascript onNovember 08, 2017

本文实例讲述了javascript自定义事件功能与用法。分享给大家供大家参考,具体如下:

概述

自定义事件很难派上用场?

为什么自定义事件很难派上用场,因为以前js不是模块化开发,也很少协作。因为事件本质是一种通信方式,是一种消息,只有存在多个对象,多个模块的情况下,才有可能需要用到事件进行通信。而现在有了模块化之后,已经可以使用自定义事件进行各模块间协作了。

哪里用得到自定义事件?

事件本质是一种消息,事件模式本质上是观察者模式的实现,那么用得上观察者模式的地方,自然也可以也可以用上事件模式。所以,如果:

1、一个目标对象改变,需要多个观察者调整自身的。

比如:我需要元素A点击之后,元素B显示鼠标的位置,元素C显示提示,元素D.....

2、分模块协作需要解耦的

比如:甲负责模块A,乙负责模块B,模块B需要A运行完之后才能运行

传统的写法将逻辑写在一个方法里面:

function doSomething(){
  A();
  B();
}

这样做每次扩展都要修改a的点击函数,不好扩展。

自定义事件的写法

//1、创建事件
var clickElem = new Event("clickElem");
//2、注册事件监听器
elem.addEventListener("clickElem",function(e){
  //干点事
})
//3、触发事件
elem.dispatchEvent(clickElem);

可以看到,elem通过dispatchEvent方法触发的事件,只有elem上注册的监听器才能监听得到。这就很没意思了,自己发给自己消息,通知自己去干什么。

创建自定义事件可参考: MDN : Creating_and_triggering_events

应用

从前面 js 自定义事件 的描述中知道:元素A通过dispatchEvent方法触发的事件,只有A上注册的监听器才能监听得到。

我们想要的效果是,别的对象干了某件事之后, 发个消息给我们,好让我们能做相应的改变。要做到这样,也不是没办法:我们可以在一个公共对象上监听和触发事件,这就很有意义了。

例子一:通知多个对象

要实现 元素A点击之后,元素B显示鼠标的位置,元素C显示提示,可以这样写:

文件:a.js

import b from "./b"
import c from "./c"
var a = document.getElementById("a");
a.addEventListener("click",function(e){
  var clickA = new Event("clickA");
  document.dispatchEvent(clickA);
});

注意:import进来的变量虽然不使用,但是一定不能省略

文件b.js:

var b = document.getElementById("b");
document.addEventListener("clickA",function(e){
  b.innerHTML = "(128,345)";
})

文件c.js:

var c = document.getElementById("c");
document.addEventListener("clickA",function(e){
  c.innerHTML = "你点了A";
})

这样写,三个模块之间完全不用关心对象,也不知道对方存在,耦合度非常的低,完全可以独立编写,不会互相影响。这其实就是一个观察者模式的实现。

例子二:游戏框架

要开发一个游戏,启动游戏,加载图片和音乐,加载完后,渲染场景和音效,加载和渲染由不同的人负责。可以这样写:

文件:index.js

import loadImage from "./loadImage"
import loadMusic from "./loadMusic"
import initScene from "./initScene"  
var start = document.getElementById("start");
start.addEventListener("click",function(e){
  console.log("游戏开始!");
  document.dispatchEvent(new Event("gameStart"));
})

文件:loadImage.js

// 加载图片
document.addEventListener("gameStart",function(){
  console.log("加载图片...");
  setTimeout(function(){
    console.log("加载图片完成");
    document.dispatchEvent(new Event("loadImageSuccess"));
  },1000);
});

文件:loadMusic.js

//加载音乐
document.addEventListener("gameStart",function(){
  console.log("加载音乐...");
  setTimeout(function(){
    console.log("加载音乐完成");
    document.dispatchEvent(new Event("loadMusicSuccess"));
  },2000);
});

文件:initScene.js

//渲染场景
document.addEventListener("loadImageSuccess",function(e){
  console.log("使用图片创建场景...");
  setTimeout(function(){
    console.log("创建场景完成");
  },2000)
});
//渲染音效
document.addEventListener("loadMusicSuccess",function(e){
  console.log("使用音乐创建音效...");
  setTimeout(function(){
    console.log("创建音效完成");
  },500)
});

加载模块和渲染模块互不影响,易于扩展。

携带信息

除此之外,事件还能传递自定义信息:

var event = new CustomEvent('myEvent', { 'dataName': dataContent });
document.dispatchEvent(event);

(注意:传递自定义信息需要使用CustomEvent,而不是Event)

然后在监听函数里取出:

document.addEventListener("myEvent",function(e){
  console.log(e.dataName);
})

这个功能非常有用!

Javascript 相关文章推荐
JAVASCRIPT IE 与 FF中兼容问题小结
Feb 18 Javascript
IE8 兼容性问题(属性名区分大小写)
Jun 04 Javascript
js 禁止选择功能实现代码(兼容IE/Firefox)
Apr 23 Javascript
JavaScript实现快速排序(自已编写)
Dec 19 Javascript
html5的自定义data-*属性和jquery的data()方法的使用示例
Aug 21 Javascript
node.js中的http.createServer方法使用说明
Dec 14 Javascript
JQuery报错Uncaught TypeError: Illegal invocation的处理方法
Mar 13 Javascript
jQuery form 表单验证插件(fieldValue)校验表单
Jan 24 Javascript
js微信扫描二维码登录网站技术原理
Dec 01 Javascript
Ant Design Vue 添加区分中英文的长度校验功能
Jan 21 Javascript
Element Dropdown下拉菜单的使用方法
Jul 26 Javascript
浅谈JS的原型和原型链
Jun 04 Javascript
详解在vue-cli中引用jQuery、bootstrap以及使用sass、less编写css
Nov 08 #jQuery
ES6中javascript实现函数绑定及类的事件绑定功能详解
Nov 08 #Javascript
手把手教你使用vue-cli脚手架(图文解析)
Nov 08 #Javascript
vue中实现滚动加载更多的示例
Nov 08 #Javascript
详解使用webpack打包编写一个vue-toast插件
Nov 08 #Javascript
结合mint-ui移动端下拉加载实践方法总结
Nov 08 #Javascript
详解如何使用webpack在vue项目中写jsx语法
Nov 08 #Javascript
You might like
Fatal error: Call to undefined function curl_init()解决方法
2010/04/09 PHP
PHP用PDO如何封装简单易用的DB类详解
2017/07/30 PHP
PHP中的self关键字详解
2019/06/23 PHP
Javascript调试工具(下载)
2007/01/09 Javascript
四种参数传递的形式——URL,超链接,js,form表单
2015/07/24 Javascript
七夕情人节丘比特射箭小游戏
2015/08/20 Javascript
js实现的tab标签切换效果代码分享
2015/08/25 Javascript
jQuery根据表单name获取值的方法
2016/05/24 Javascript
微信小程序 前端源码逻辑和工作流详解
2016/10/08 Javascript
Express框架之connect-flash详解
2017/05/31 Javascript
vue中如何让子组件修改父组件数据
2018/06/14 Javascript
vscode下vue项目中eslint的使用方法
2019/01/13 Javascript
js中对象和面向对象与Json介绍
2019/01/21 Javascript
使用weixin-java-miniapp配置进行单个小程序的配置详解
2019/03/29 Javascript
关于vue.js中实现方法内某些代码延时执行
2019/11/14 Javascript
openLayer4实现动态改变标注图标
2020/08/17 Javascript
[56:46]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 VP vs Effect
2018/04/01 DOTA
Python的消息队列包SnakeMQ使用初探
2016/06/29 Python
Python 性能优化技巧总结
2016/11/01 Python
python 表达式和语句及for、while循环练习实例
2017/07/07 Python
python中subprocess批量执行linux命令
2018/04/27 Python
python 爬虫一键爬取 淘宝天猫宝贝页面主图颜色图和详情图的教程
2018/05/22 Python
关于Python的一些学习总结
2018/05/25 Python
详解python里的命名规范
2018/07/16 Python
python+selenium定时爬取丁香园的新型冠状病毒数据并制作出类似的地图(部署到云服务器)
2020/02/09 Python
阿迪达斯德国官方网站:adidas德国
2017/07/12 全球购物
在线购买澳大利亚设计师手拿包和奢华晚装手袋:Olga Berg
2019/03/20 全球购物
Dogeared官网:在美国手工制作的珠宝
2019/08/24 全球购物
Ellos瑞典官网:北欧地区时尚、美容和住宅领域领先的电子商务网站
2019/11/21 全球购物
新锐科技Java程序员面试题
2016/07/25 面试题
大学本科毕业生求职简历的自我评价
2013/10/09 职场文书
中学生励志演讲稿
2014/04/26 职场文书
平安工地建设方案
2014/05/06 职场文书
预备党员转正材料
2014/12/19 职场文书
经理聘任证明
2015/03/02 职场文书
丧事主持词
2015/07/02 职场文书