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实现禁止后退的方法
Dec 27 Javascript
修改好的jquery滚动字幕效果实现代码
Jun 22 Javascript
关于eval 与new Function 到底该选哪个?
Apr 17 Javascript
原生Js页面滚动延迟加载图片实现原理及过程
Jun 24 Javascript
Javascript学习笔记之函数篇(四):arguments 对象
Nov 23 Javascript
Javascript前端UI框架Kit使用指南之kitjs的对话框组件
Nov 28 Javascript
详解JavaScript ES6中的Generator
Jul 28 Javascript
实现高性能JavaScript之执行与加载
Jan 30 Javascript
实现隔行换色效果的两种方式【实用】
Nov 27 Javascript
原生js的ajax和解决跨域的jsonp(实例讲解)
Oct 16 Javascript
详解关于vue-area-linkage走过的坑
Jun 27 Javascript
Vue常用传值方式、父传子、子传父及非父子实例分析
Feb 24 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下操作Linux消息队列完成进程间通信的方法
2010/07/24 PHP
使ecshop模板中可引用常量的实现方法
2011/06/02 PHP
解析web文件操作常见安全漏洞(目录、文件名检测漏洞)
2013/06/29 PHP
memcache一致性hash的php实现方法
2015/03/05 PHP
php模式设计之观察者模式应用实例分析
2019/09/25 PHP
jQuery 1.0.2
2006/10/11 Javascript
jQuery 表格插件整理
2010/04/27 Javascript
jQuery 学习第六课 实现一个Ajax的TreeView
2010/05/17 Javascript
一些经常会用到的Javascript检测函数
2010/05/31 Javascript
浅析JavaScript原型继承的陷阱
2013/12/03 Javascript
jQuery中:disabled选择器用法实例
2015/01/04 Javascript
jQuery旋转插件jqueryrotate用法详解
2016/10/13 Javascript
详解vue.js组件化开发实践
2016/12/14 Javascript
Angular 4 依赖注入学习教程之FactoryProvider的使用(四)
2017/06/04 Javascript
AngularJS常见过滤器用法实例总结
2017/07/06 Javascript
layui 图片上传+表单提交+ Spring MVC的实例
2019/09/21 Javascript
浅谈webpack构建工具配置和常用插件总结
2020/05/11 Javascript
JavaScript中展开运算符及应用的实例代码
2021/01/14 Javascript
[41:17]VG vs Optic 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
Python基础教程之正则表达式基本语法以及re模块
2016/03/25 Python
python 与GO中操作slice,list的方式实例代码
2017/03/20 Python
Python3列表内置方法大全及示例代码小结
2019/05/10 Python
python datetime中strptime用法详解
2019/08/29 Python
CSS3中的clip-path使用攻略
2015/08/03 HTML / CSS
美国羊皮公司:Overland
2018/01/15 全球购物
Groupon比利时官方网站:特卖和网上购物高达-70%
2019/08/09 全球购物
荷兰浴室和卫浴网上商店:Badkamerxxl.nl
2020/10/06 全球购物
比较基础的php面试题及答案-填空题
2014/04/26 面试题
学术会议欢迎词
2014/01/09 职场文书
个人作风剖析材料
2014/02/02 职场文书
高中课前三分钟演讲稿
2014/09/13 职场文书
毕业实习自我鉴定范文2014
2014/09/26 职场文书
镇党委书记群众路线整改措施思想汇报
2014/10/13 职场文书
死者家属慰问信
2015/03/24 职场文书
企业团队精神心得体会
2016/01/19 职场文书
MySQL磁盘碎片整理实例演示
2022/04/03 MySQL