javascript自定义事件应用实例

可以先看例子


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);
})

这个功能非常有用!

使用自定义事件的优缺点

优点: 各模块之间低耦合

缺点:不好定位问题,容易导致诡秘的错误。曾在一个项目上用到自定义事件,大体如下:

let i = 0;
document.addEventListener("EventA",function(){
   i++;
   document.dispatchEvent(new Event("EventB"));
})

document.addEventListener("EventB",function(){
    i++;
    document.dispatchEvent(new Event("EventA")); //这句是不小心多加的 
    if(true){
       document.dispatchEvent(new Event("EventC"));
    }
})

document.addEventListener("EventC",function(){
   i++;
   console.log("i的值是:",i);
})

你会发现得到一个很怪异的结果,仅仅是多加一句,整个程序的流程就完完全全的改变了,而且很难定位问题。

要解决这种问题,好好的打印日志或许是一个办法。

猜你喜欢

转载自blog.csdn.net/ruangong1203/article/details/52474452