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 相关文章推荐
今天是星期几的4种JS代码写法
Sep 17 Javascript
Jquery uploadify图片上传插件无法上传的解决方法
Dec 16 Javascript
JS获取单击按钮单元格所在行的信息
Jun 17 Javascript
jQuery插件EnPlaceholder实现输入框提示文字
Jun 05 Javascript
jQuery的Scrollify插件实现滑动到页面下一节点
Jul 05 Javascript
AngularJs html compiler详解及示例代码
Sep 01 Javascript
Javascript 跨域知识详细介绍
Oct 30 Javascript
vue项目每30秒刷新1次接口的实现方法
Dec 04 Javascript
vue 移动端注入骨架屏的配置方法
Jun 25 Javascript
vue中实现点击变成全屏的多种方法
Sep 27 Javascript
如何在vue 中引入使用jquery
Nov 10 jQuery
微信小程序canvas实现签名功能
Jan 19 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 中的str_replace 函数总结
2007/04/27 PHP
(PHP实现)只使用++运算实现加法,减法,乘法,除法
2013/06/27 PHP
PHP IE中下载附件问题解决方法
2014/01/07 PHP
php随机生成数字字母组合的方法
2015/03/18 PHP
PHP动态地创建属性和方法, 对象的复制, 对象的比较,加载指定的文件,自动加载类文件,命名空间
2016/05/06 PHP
php array_values 返回数组的值实例详解
2016/11/17 PHP
PHP开发实现微信退款功能示例
2017/11/25 PHP
thinkphp3.2同时连接两个数据库的简单方法
2019/08/13 PHP
Javascript typeof 用法
2008/12/28 Javascript
滚动条变色 隐藏滚动条与双击网页自动滚屏显示代码
2009/12/28 Javascript
基于jquery的仿百度的鼠标移入图片抖动效果
2010/09/17 Javascript
javascript 数组排序函数sort和reverse使用介绍
2013/11/21 Javascript
Yii2使用Bootbox插件实现自定义弹窗
2015/04/02 Javascript
jQuery实现TAB风格的全国省份城市滑动切换效果代码
2015/08/24 Javascript
深入理解JavaScript中的尾调用(Tail Call)
2017/02/07 Javascript
基于 Vue 的树形选择组件的示例代码
2017/08/18 Javascript
vue组件间通信子与父详解(二)
2017/11/07 Javascript
Next.js项目实战踩坑指南(笔记)
2018/11/29 Javascript
微信小程序使用map组件实现解析经纬度功能示例
2019/01/22 Javascript
[16:43]Heroes19_剃刀(完美)
2014/10/31 DOTA
Python中最大最小赋值小技巧(分享)
2017/12/23 Python
python实现在pandas.DataFrame添加一行
2018/04/04 Python
解决python3 Pycharm上连接数据库时报错的问题
2018/12/03 Python
selenium+PhantomJS爬取豆瓣读书
2019/08/26 Python
Python reversed函数及使用方法解析
2020/03/17 Python
django实现HttpResponse返回json数据为中文
2020/03/27 Python
Python实现Excel自动分组合并单元格
2021/02/22 Python
美国领先的医疗警报服务:Philips Lifeline
2018/03/12 全球购物
舞会礼服和舞会鞋:PromGirl
2019/04/22 全球购物
Derek Rose官网:英国高档睡衣、家居服和内衣品牌
2020/01/18 全球购物
美国一家著名的手表在线折扣网站:Discount Watch Store
2020/02/24 全球购物
师范教师大学生职业生涯规划范文
2014/01/05 职场文书
学生会干部自荐信
2014/02/04 职场文书
培训简讯范文
2015/07/20 职场文书
《生物入侵者》教学反思
2016/02/16 职场文书
spring cloud eureka 服务启动失败的原因分析及解决方法
2022/03/17 Java/Android