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 相关文章推荐
JS 非图片动态loading效果实现代码
Apr 09 Javascript
Colortip基于jquery的信息提示框插件在IE6下面的显示问题修正方法
Dec 06 Javascript
利用百度地图JSAPI生成h7n9禽流感分布图实现代码
Apr 15 Javascript
Bootstrap树形控件使用方法详解
Jan 27 Javascript
js实现键盘自动打字效果
Dec 23 Javascript
详解微信第三方小程序代开发
Jun 23 Javascript
浅谈如何使用webpack构建多页面应用
May 30 Javascript
JS获取指定月份的天数两种实现方法
Jun 22 Javascript
在 Angular6 中使用 HTTP 请求服务端数据的步骤详解
Aug 06 Javascript
Vue+ElementUI使用vue-pdf实现预览功能
Nov 26 Javascript
javascript实现点击按钮切换轮播图功能
Sep 23 Javascript
抖音短视频(douyin)去水印工具的实现代码
Mar 30 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
连接到txt文本的超链接,不直接打开而是点击后下载的处理方法
2009/07/01 PHP
CodeIgniter使用smtp服务发送html邮件的方法
2015/06/10 PHP
php和redis实现秒杀活动的流程
2019/07/17 PHP
Array对象方法参考
2006/10/03 Javascript
jquery跟js初始化加载的多种方法及区别介绍
2014/04/02 Javascript
JavaScript实现简单图片翻转的方法
2015/04/17 Javascript
javascript常用正则表达式汇总
2015/07/31 Javascript
jQuery如何跳转到另一个网页 就这么简单
2016/12/28 Javascript
JavaScript你不知道的一些数组方法
2017/08/18 Javascript
Vue引入sass并配置全局变量的方法
2018/06/27 Javascript
小程序自定义组件实现城市选择功能
2018/07/18 Javascript
Vue.js 十五分钟入门图文教程
2018/09/12 Javascript
vue-cli项目修改文件热重载失效的解决方法
2018/09/19 Javascript
JS实现图片拖拽交换效果
2018/11/30 Javascript
如何为你的JS项目添加智能提示与类型检查详解
2019/03/12 Javascript
Vue 2.0 侦听器 watch属性代码详解
2019/06/19 Javascript
浅谈vue中$bus的使用和涉及到的问题
2020/07/28 Javascript
python装饰器使用方法实例
2013/11/21 Python
python发送伪造的arp请求
2014/01/09 Python
python中单下划线_的常见用法总结
2018/07/10 Python
python3 unicode列表转换为中文的实例
2018/10/26 Python
Python 项目转化为so文件实例
2019/12/23 Python
python scrapy重复执行实现代码详解
2019/12/28 Python
Python 通过监听端口实现唯一脚本运行方式
2020/05/05 Python
深入解读CSS3中transform变换模型的渲染
2016/05/27 HTML / CSS
锐步美国官方网站:Reebok美国
2018/01/10 全球购物
美国高级工作服品牌:Carhartt
2018/01/25 全球购物
Rhone官方网站:男士运动服装、健身服装和高级运动服
2019/05/01 全球购物
DNA基因检测和分析:23andMe
2019/05/01 全球购物
介绍一下linux的文件权限
2014/07/20 面试题
品牌推广活动策划方案
2014/08/19 职场文书
2014年政府采购工作总结
2014/12/09 职场文书
初中开学典礼新闻稿
2015/07/17 职场文书
幼儿教师三分钟演讲稿
2019/06/21 职场文书
python实现自动化群控的步骤
2021/04/11 Python
Go语言特点及基本数据类型使用详解
2022/03/21 Golang