js中事件(自定义事件)

  今天闲的蛋疼,我们来聊一聊web前端中的事件机制和自定义事件。灵感来自jQuery,在此感谢jQuery作者。

  首先,最开始。

<button id="button" type="button" onclick="alert(‘hello‘)">你好</button>

  这是我们在使用html写页面的时候最原生的事件触发方式。上面那行代码会生成一个按钮,当我们点击这个按钮的时候就会弹出一个原生的弹窗,内容是hello。

  随着技术的发展,我们认为事件要和html结构分开,于是就演化出了这么一种写法。

<button id="button" type="button">你好</button>
<script>
var button = document.getElementById("button");
button.onclick = function(){  alert("hello");
}
</script>

  以上代码的效果和第一个一样,但是实现了事件与html的分离。

  和上面的代码采用一样的原理,可以为各种各样元素添加各种各样事件。比如说keyup、mouseover等。

  那我们对js最原生的事件有了一定的了解后,我们就会想,我们能不能自定义事件呢?比如说,我们希望在按一个按钮的时候触发一个save事件。我们发现原生的js中没有save事件,怎么办,难道就这么放弃吗?

  于是我们就考虑了,事件的本质在于消息的传递。那我们把save写成一个函数,当我们点击按钮的时候执行该函数,不就变相的实现了这个自定义事件吗?

<button id="button" type="button">你好</button>
<script>
var button = document.getElementById("button");
button.onclick = function(){
     save();
}
var save = function(){
     alert("save");
}
</script>

  是啊,实现是实现了,但我们就觉得这个方法好挫啊,而且我们如果想要为save定义多个事件,就会发现,后一个事件会覆盖前一个事件这就相当的蛋疼了。

  那我们可不可以这样,将save事件弄成一个函数数组,在触发的时候顺序触发这个数组中的每一个函数,这样我们不就可以触发多个方法了?然后我们如果需要为该事件添加新的方法,只要在这个数组中添加新的项就可以啦。

<button id="button" type="button">你好</button>
<script>
var button = document.getElementById("button");
button.onclick = function(){
    trigger(save);
}
var trigger = function(){
    for(var i in save){
        save[i]();
    }
}
var save1 = function(){
    alert("save1");
}
var save2 = function(){
    alert("save2");
}
var save = [save1,save2];
</script>

  以上的代码会顺序弹出save1和save2。使用同样的方法我们可以为原生的事件添加多个函数方法。(是不是有点类似于addEventListener和attachEvent?)

  看着上面的代码还是有点不爽,为什么呢?因为没有上面提到的那两个方法帅呀。哈哈。

  我们的方法优势在于可以添加自定义事件,而原生的方法不但执行效率比我们高,使用也比咱们便利,感觉好不爽。

  我们重新设计一下,刚才说原生的方法比咱们便利,那我们就进行统一化尽力提高便利性。我们刚才的分析中提到了,原生的事件和自定义的事件都可以通过以上的方法来玩。那我们就不要管是原生的还是自定义的了。

  事件可能有哪几种操作,我这里只想到了,添加、移除、触发以及挂靠到原生事件上。那我们可以定义addEvent()添加事件、removeEvent()移除事件、trigger()触发事件、dispatchEvent()挂靠事件。

  这里就不提供源代码了,如果有兴趣可以去查看jQuery源码,推荐看低版本,比如说1.0.4那里的事件机制是最原始的,也是最易懂的。

  addEvent()

    1、需要检测事件数组是否存在,如果不存在定义一个数组,这个数组用于存放事件的所有方法,执行2。否则执行3

    2、将挂载在元素上的事件方法添加到该数组中。执行3

    3、将函数参数中传入的事件方法添加到事件数组中。执行4

    4、将函数数组挂载带元素上。

  removeEvent()

    1、通过传入参数找到事件数组中想要移除的事件方法。执行2

    2、移除对应事件方法。

  trigger()

    1、依次执行事件数组中的每一个函数方法即可。

  dispatchEvent()

    1、将事件数组的触发函数挂载到元素的执行函数上。只要完成下面代码的效果即可。

<button id="button" type="button">你好</button>
<script>
var button = document.getElementById("button");
var handler = function(type){
    //这是事件数组触发函数
}
button.onclick = handler(click);
</script>

  写了这么多,还是感觉好不爽怎么办,为什么呢?我要是一次性触发了好多好多事件,那我们就不好理解这些事件的执行顺序了。

  于是,我们可以设置一个全局的事件队列,触发函数触发事件的时候,不直接执行函数方法,而是在事件队列中添加一个信号。而全局的事件队列定时的检测是否有新的事件产生(比如100毫秒检测一次,实际上不会带来多大的系统开销。)如果有新的事件产生,就执行对应的函数方法。这样的好处在于有利于用户控制每个事件的执行顺序(只要调整事件队列中的顺序即可),从而达到很多意想不到的效果。

时间: 2024-12-28 00:41:06

js中事件(自定义事件)的相关文章

js中的Dom事件模型以及表格方面等内容

1.实现评论页面的制作 <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> #outside{ width: 1000px; margin: 0 auto; border: 1px solid #E7EAEE; overflow: hidden; pad

JS中的计时器事件

JS可以实现很多java代码不易完成的功能.这里学习一些js中的计时器事件. JavaScript 一个设定的时间间隔之后来执行代码,称之为计时事件. 主要通过两个方法来实现: 1.setInterval() - 间隔指定的毫秒数不停地执行指定的代码. 2.setTimeout() - 暂停指定的毫秒数后执行指定的代码 并且,这两个方法都是window对象的方法. 首先,介绍setInterval()方法,该方法值得是间隔一定的毫秒数不停的执行指定的代码. 语法:window.setInterv

js中获取键盘事件

1 <script type="text/javascript" language=JavaScript charset="UTF-8"> 2 document.onkeydown=function(event){ 3 var e = event || window.event || arguments.callee.caller.arguments[0]; 4 if(e && e.keyCode==27){ // 按 Esc 5 //要

wpf自定义控件中使用自定义事件

wpf自定义控件中使用自定义事件 1 创建自定义控件及自定义事件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36     /// <summary>     /// 演示用的自定义控件     /// </summary>     public class ExtButton : Button     {         public

JS的三种使用方式/CSS的三种使用方式/JS中的DOM事件模型/JS中匿名函数的书写及调用/媒体查询@media的三种使用方式

一.JS的三种使用方式 1.html标签中内嵌JS(不提倡使用.)                <button onclick="javascript:alert('你真点啊.')" > 有本事点我呀!!!!</button>                                2.HTML页面中直接使用JS:                <script type="text/javascript">        

js中的计时器事件`setTimeout()` 和 `setInterval()`

js中的计时器事件 在js中,通常会有一些事件,我们需要让它 间隔一段时间之后再发生,或者 每隔一段时间 发生一次,那就需要用到我们js中的计时事件 计时事件主要有两种: setTimeout() ---- 间隔一定的时间之后执行 setInterval() ----每间隔一定的时间执行一次(重复性执行) setTimeout() 间隔一定的时间之后`执行指定的语句或函数. 例如:3s后跳转到前一个页面. <script type="text/javascript"> se

什么是vue.js中的自定义指令?

问题一:什么是vue.js中的自定义指令? 自定义一些指令对底层DOM进行操作 更多参考 Vue里面有许多内置的指令,比如v-if和v-show,这些丰富的指令能满足我们的绝大部分业务需求,不过在需要一些特殊功能时,我们仍然希望对DOM进行底层的操作,这时就要用到自定义指令. 问题二:自定义指令的几个钩子函数 bind:只调用一次,指令第一次绑定到元素时调用.在这里可以进行一次性的初始化设置. inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中). upda

js中鼠标滚轮事件详解

(以下内容部分内容参考了http://adomas.org/javascript-mouse-wheel/ ) 之前js 仿Photoshop鼠标滚轮控制输入框取值中已使用js对鼠标滚轮事件进行控制,滚轮事件其中考虑浏览器兼容性问题 附加事件 其中经我测试,IE/Opera属于同一类型,使用attachEvent即可添加滚轮事件. /*IE注册事件*/ if(document.attachEvent){ document.attachEvent('onmousewheel',scrollFunc

DragonBones龙骨骨骼中的自定义事件(另有声音、动画事件)

参考: DragonBones骨骼动画事件系统详解 一.在DragonBones中添加自定义事件帧 动画制作时 时间轴拉到最下面有一个事件层,添加一个事件帧 左边属性面板定义自定义事件 二.Egret中监听事件 新建一个测试用骨骼动画test //新建测试用骨骼动画 let armatureDisplay:dragonBones.EgretArmatureDisplay; let factory = dragonBones.EgretFactory.factory; factory.parseD

js:实现自定义事件对象接口

网易2017内推笔试题 要求: 请实现下面的自定义事件Event对象的接口,功能见注释(测试1) 该Event对象的接口需要能被其他对象拓展复用(测试2) 1 //测试1 2 Event.on('test',function(result){ 3 console.log(result); 4 }); 5 Event.on('test',function(){ 6 console.log('test'); 7 }); 8 Event.emit('test','hello world'); //输出