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截取字符串(通过substring实现并支持中英文混合)
Jun 24 Javascript
图片动画横条广告带上下滚动可自定义图片、链接等等
Oct 20 Javascript
多种方法实现load加载完成后把图片一次性显示出来
Feb 19 Javascript
理解javascript中的原型和原型链
Jul 30 Javascript
JS实现鼠标滑过链接改变网页背景颜色的方法
Oct 20 Javascript
jQuery实现打开页面渐现效果示例
Jul 27 Javascript
jQuery纵向导航菜单效果实现方法
Dec 19 Javascript
React学习笔记之条件渲染(一)
Jul 02 Javascript
ES6中Class类的静态方法实例小结
Oct 28 Javascript
Vuex中mutations与actions的区别详解
Mar 01 Javascript
jQuery实现的鼠标拖动画矩形框示例【可兼容IE8】
May 17 jQuery
element-ui table行点击获取行索引(index)并利用索引更换行顺序
Feb 27 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
提升PHP执行速度全攻略(上)
2006/10/09 PHP
jquery+ashx无刷新GridView数据显示插件(实现分页、排序、过滤功能)
2010/04/25 Javascript
jquery下实现overlay遮罩层代码
2010/08/25 Javascript
jquery ajax方式直接提交整个表单核心代码
2013/08/15 Javascript
JQuery结合CSS操作打印样式的方法
2013/12/24 Javascript
JavaScript用Number方法实现string转int
2014/05/13 Javascript
随鼠标移动的时钟非常漂亮遗憾的是只支持IE
2014/08/12 Javascript
Nodejs异步回调的优雅处理方法
2014/09/25 NodeJs
jquery渐隐渐显的图片幻灯闪烁切换实现方法
2015/02/26 Javascript
JavaScript——DOM操作——Window.document对象详解
2016/07/14 Javascript
基于JS组件实现拖动滑块验证功能(代码分享)
2016/11/18 Javascript
利用nodejs监控文件变化并使用sftp上传到服务器
2017/02/18 NodeJs
详解使用grunt完成requirejs的合并压缩和js文件的版本控制
2017/03/02 Javascript
详谈Angular 2+ 的表单(一)之模板驱动型表单
2017/04/25 Javascript
JavaScript箭头(arrow)函数详解
2017/06/04 Javascript
jQuery扩展方法实现Form表单与Json互相转换的实例代码
2018/09/05 jQuery
[59:32]Liquid vs Fnatic 2019国际邀请赛淘汰赛败者组BO1 8.20.mp4
2020/07/19 DOTA
python算法学习之基数排序实例
2013/12/18 Python
Python反射用法实例简析
2017/12/22 Python
python实现简单登陆系统
2018/10/18 Python
Python爬虫实战之12306抢票开源
2019/01/24 Python
python统计函数库scipy.stats的用法解析
2020/02/25 Python
python实现贪吃蛇游戏源码
2020/03/21 Python
波兰运动鞋网上商店:e-Sporting
2018/02/16 全球购物
学习党章思想汇报
2014/01/07 职场文书
五一服装活动方案
2014/01/11 职场文书
导游个人求职信范文
2014/03/23 职场文书
药品业务员岗位职责
2014/04/17 职场文书
公务员试用期满考核材料
2014/05/22 职场文书
医院深入开展党的群众路线教育实践活动实施方案
2014/08/27 职场文书
2014年九一八事变演讲稿
2014/09/14 职场文书
2015届本科毕业生自我鉴定
2014/09/27 职场文书
2015年酒店工作总结范文
2015/04/07 职场文书
html5中sharedWorker实现多页面通信的示例代码
2021/05/07 Javascript
Mysql 数据库中的 redo log 和 binlog 写入策略
2022/04/26 MySQL