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 相关文章推荐
两个select之间option的互相添加操作(jquery实现)
Nov 12 Javascript
ASP.NET jQuery 实例10 动态修改hyperlink的URL值
Feb 03 Javascript
jquery多行滚动/向左或向上滚动/响应鼠标实现思路及代码
Jan 23 Javascript
jQuery setTimeout传递字符串参数报错的解决方法
Jun 09 Javascript
Js和JQuery获取鼠标指针坐标的实现代码分享
May 25 Javascript
JavaScript数组的定义及数字操作技巧
Jun 06 Javascript
微信小程序开发之map地图实现教程
Jun 08 Javascript
详细介绍RxJS在Angular中的应用
Sep 23 Javascript
Vue.js组件间的循环引用方法示例
Dec 27 Javascript
Jquery让form表单异步提交代码实现
Nov 14 jQuery
如何利用javascript接收json信息并进行处理
Aug 06 Javascript
vue router 动态路由清除方式
May 25 Vue.js
详解在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
解析二进制流接口应用实例 pack、unpack、ord 函数使用方法
2013/06/18 PHP
php命令行用法入门实例教程
2014/10/27 PHP
php判断访问IP的方法
2015/06/19 PHP
浅析PHP7新功能及语法变化总结
2016/06/17 PHP
TP5框架实现签到功能的方法分析
2020/04/05 PHP
解析javascript 数组以及json元素的添加删除
2013/06/26 Javascript
js中的preventDefault与stopPropagation详解
2014/01/29 Javascript
jQuery插件HighCharts实现的2D面积图效果示例【附demo源码下载】
2017/03/15 Javascript
jQuery绑定事件方法及区别(bind,click,on,live,one)
2017/08/14 jQuery
webpack+vue中使用别名路径引用静态图片地址
2017/11/20 Javascript
JavaScript原生实现观察者模式的示例
2017/12/15 Javascript
vue监听键盘事件的快捷方法【推荐】
2018/07/11 Javascript
nodejs遍历文件夹下并操作HTML/CSS/JS/PNG/JPG的方法
2018/11/01 NodeJs
微信小程序动态显示项目倒计时
2019/06/20 Javascript
前端Vue项目详解--初始化及导航栏
2019/06/24 Javascript
JavaScript this使用方法图解
2020/02/04 Javascript
[04:10]DOTA2英雄梦之声_第11期_圣堂刺客
2014/06/21 DOTA
python实现上传样本到virustotal并查询扫描信息的方法
2014/10/05 Python
对于Python中RawString的理解介绍
2016/07/07 Python
python实现神经网络感知器算法
2017/12/20 Python
python将文本中的空格替换为换行的方法
2018/03/19 Python
python读取excel指定列数据并写入到新的excel方法
2018/07/10 Python
python实现Dijkstra静态寻路算法
2019/01/17 Python
对python列表里的字典元素去重方法详解
2019/01/21 Python
python return逻辑判断表达式实现解析
2019/12/02 Python
css3实现可滑动跳转的分页插件示例
2014/05/08 HTML / CSS
HTML5 Canvas中绘制矩形实例
2015/01/01 HTML / CSS
澳大利亚制造的羊皮靴:Original UGG Boots
2017/11/13 全球购物
耐克中国官方商城:Nike中国
2018/10/18 全球购物
应届大学生自荐信
2013/12/05 职场文书
设计师求职信模板
2014/05/06 职场文书
统计专业自荐书
2014/07/06 职场文书
高中课前三分钟演讲稿
2014/08/18 职场文书
2015年推广普通话演讲稿
2015/03/20 职场文书
基于Go Int转string几种方式性能测试
2021/04/28 Golang
Mysql存储过程、触发器、事件调度器使用入门指南
2022/01/22 MySQL