怎么用javascript实现自定义事件功能

怎么用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实现自定义事件功能,发布者:亿速云,转载请注明出处:https://worktile.com/kb/p/20940

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
亿速云的头像亿速云认证作者
上一篇 2022年8月27日 下午4:54
下一篇 2022年8月27日 下午4:55

相关推荐

  • Java Bean转Map的坑怎么解决

    一、背景 有些业务场景下需要将 Java Bean 转成 Map 再使用。 以为很简单场景,但是坑很多。 二、那些坑 2.0 测试对象 import lombok.Data;import java.util.Date;@Datapublic class MockObject extends Mock…

    2022年9月15日
    85300
  • MyBatisPlus QueryWrapper多条件查询及修改方法是什么

    gt、ge、lt、le、isNull、isNotNull 大于 > 例: gt(“age”, 18) → age > 18 ge 大于等于 >= 例: ge(“age”, 18) → age &gt…

    2022年9月21日
    1.6K00
  • cad文件的后缀有哪些

    cad文件的后缀:1、“.Dwg”,Dwg格式是cad文件的标准文件格式;2、“.dxf”,dxf格式是一种绘图交换文件,是进行CAD数据交换的CAD数据文件格式;3、“.dws”,dws格式的cad文档只能查看不能修改;4、“.dwt”,dwt是CAD的模板文件。 本教程操作环境:windows1…

    2022年9月8日
    1.9K00
  • MySQL如何解决delete大量数据后空间不释放的问题

    MySQL 的几种碎片整理方案总结(解决delete大量数据后空间不释放的问题) 1.背景知识? 1.1 为什么会有碎片? MySQL 中 insert 与 update 都可能导致页分裂,这样就存在碎片。 对于大量的UPDATE,也会产生文件碎片化 , Innodb的最小物理存储分配单位是页(pa…

    2022年9月16日
    5.9K00
  • SQL Server备份数据库的方法

    一.首先把当前的数据库备份成一个文件 1.按照操作来,选择对应的数据库, 确定备份文件的存储位置 点击确定,生成备份文件。 2.然后可以通过该备份文件还原数据库。 右键数据库点击还原文件和文件组 然后设置目标数据库的名字,如果数据库中已经存在相同名字的,则需要修改或者删除原来同名的数据库,然后在选择…

    2022年9月11日
    55400
  • MySQL触发器如何创建与删除

    1.为什么需要触发器 有一些表是互相关联的,比如说商品表和库存表,我们对商品表的数据进行操作,那么对应的库存表还得发生变化,这样才可以保证数据的完整。如果我们是自己手动维护的话,比较麻烦。这个时候我们可以使用触发器,创建一个触发器,让商品信息数据的插入操作自动触发库存数据的插入操作等,这样我们就不需…

    2022年9月18日
    81800
  • 怎么用SVG给favicon添加标识

    一、favicon 的获取方式 想知道获取方式,可以先了解设置方式。 一般有两种方式可以设置网站的 favicon。 名列前茅种,通过 link 标签设置(需要rel=”icon”属性) <link rel=”icon” href=”xxx.png”> 第二种,直接在网站根目录放一张fa…

    2022年9月8日
    72900
  • 电脑蓝屏代码0x00000116如何解决

    解决方法: 方法一: 1、需要先重启电脑,看看能不能进入系统,进不去就再重启电脑。 2、然后在开机的时候按住键盘“F8”,进入高级选项菜单,在其中选择进入“安全模式” 3、进入安全模式,按下键盘“win+r”打开运行,输入“devmgmt.msc”回车确定。 4、然后在其中展开显示适配器,右键选中下…

    2022年9月15日
    1.0K00
  • windows驱动精灵检测不到打印机如何解决

    解决方法: 方法一: 可能是驱动安装错误或者是驱动出现了问题。 这时打开驱动精灵重新检测一遍即可。 1、进入主界面后点击“立即检测”。 2、可以选择将提示更新的驱动进行“升级”,或者直接点击“一键安装”安装驱动。 方法二: 可能是有老驱动的残留没删干净。 先将老驱动清理干净,在使用驱动精灵进行下载即…

    2022年9月10日
    58300
  • Web漏洞利用姿势的示例分析

    1、HTTP PUT方法利用 PUT是用来进行文件管理的方法,若运维人员未修改Web服务器缺省配置,依然支持这些方法,则可以向服务器文件系统任意上传文件。 1.1、 Netcat利用PUT方法 Netcat是一款非常出名的网络工具,简称“NC”,有渗透测试中的“瑞士**”之称。它可以用作端口监听、端…

    2022年9月22日
    67700
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部