欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

javascript自定义事件功能与用法实例分析

程序员文章站 2022-07-06 21:09:02
本文实例讲述了javascript自定义事件功能与用法。分享给大家供大家参考,具体如下: 概述 自定义事件很难派上用场? 为什么自定义事件很难派上用场,因为以前js不...

本文实例讲述了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);
})

这个功能非常有用!

附:点击此处查看github示例

ps:这里再为大家附上javascript系统自带事件参考表供大家参考查询:

javascript事件与功能说明大全:

更多关于javascript相关内容感兴趣的读者可查看本站专题:《javascript事件相关操作与技巧大全》、《javascript操作dom技巧总结》、《javascript错误与调试技巧总结》、《javascript数据结构与算法技巧总结》、《javascript遍历算法与技巧总结》及《javascript数学运算用法总结

希望本文所述对大家javascript程序设计有所帮助。