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 父窗口控制子窗口的行为-打开,关闭,重定位,回复
Apr 20 Javascript
图片上传判断及预览脚本的效果实例
Aug 07 Javascript
jquery自定义类似$.ajax()的方法实现代码
Aug 13 Javascript
JavaScript使用cookie记录临时访客信息的方法
Apr 07 Javascript
jQuery的remove()方法使用详解
Aug 11 Javascript
JS插件overlib用法实例详解
Dec 26 Javascript
jquery对dom节点的操作【推荐】
Apr 15 Javascript
解决vue中无法动态修改jqgrid组件 url地址的问题
Mar 01 Javascript
js核心基础之构造函数constructor用法实例分析
May 11 Javascript
JS数据类型分类及常用判断方法
Nov 19 Javascript
AngularJS实现多级下拉框
Mar 25 Javascript
TS 类型收窄教程示例详解
Sep 23 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
10条PHP高级技巧[修正版]
2011/08/02 PHP
php连接mysql数据库最简单的实现方法
2019/09/24 PHP
laravel-admin 后台表格筛选设置默认的查询日期方法
2019/10/03 PHP
javascript,jquery闭包概念分析
2010/06/19 Javascript
使用js判断控件是否获得焦点
2014/01/03 Javascript
jQuery scroll事件实现监控滚动条分页示例
2014/04/04 Javascript
jquery 中的each()跳出循环的语句
2014/05/23 Javascript
详解用vue.js和laravel实现微信支付
2017/06/23 Javascript
使用原生js+canvas实现模拟心电图的实例
2017/09/20 Javascript
Angular实现的日程表功能【可添加及隐藏显示内容】
2017/12/27 Javascript
基于vue v-for 多层循环嵌套获取行数的方法
2018/09/26 Javascript
解决vue单页面应用打包后相对路径、绝对路径相关问题
2020/08/14 Javascript
python机器学习案例教程——K最近邻算法的实现
2017/12/28 Python
linecache模块加载和缓存文件内容详解
2018/01/11 Python
对python自动生成接口测试的示例讲解
2018/11/30 Python
Python3实现的回文数判断及罗马数字转整数算法示例
2019/03/27 Python
python实现关闭第三方窗口的方法
2019/06/28 Python
关于pandas的离散化,面元划分详解
2019/11/22 Python
python中xlrd模块的使用详解
2021/02/01 Python
python包的导入方式总结
2021/03/02 Python
css3闪亮进度条效果实现思路及代码
2013/04/17 HTML / CSS
css3实例教程 一款纯css3实现的发光屏幕旋转特效
2014/12/07 HTML / CSS
波兰在线香水店:Perfumy.pl
2019/08/12 全球购物
什么是虚拟内存?虚拟内存有什么优势?
2016/02/09 面试题
高中生家长会演讲稿
2014/01/14 职场文书
幼儿园毕业寄语
2014/04/03 职场文书
2014年大学宣传部工作总结
2014/12/19 职场文书
2014年变电站工作总结
2014/12/19 职场文书
车间主任岗位职责
2015/02/03 职场文书
学校国庆节活动总结
2015/03/23 职场文书
小学数学教学反思范文
2016/02/16 职场文书
MySQL命令行操作时的编码问题详解
2021/04/14 MySQL
详解盒子端CSS动画性能提升
2021/05/24 HTML / CSS
新手入门Mysql--sql执行过程
2021/06/20 MySQL
SQLServer RANK() 排名函数的使用
2022/03/23 SQL Server
Python实现简单得递归下降Parser
2022/05/02 Python