自己封装的javascript事件队列函数版_javascript技巧
背景
javascript中使用addEventListener()或attachEvent()绑定事件时会有几个小问题:
一、使用addEventListener()或attachEvent()添加的匿名函数无法移除。
oBtn.addEventListener('click',function(){
alert('button is clicked')
},false)
oBtn.reomveEventListener('click',function(){
alert('button is clicked')
},false)
//oBtn上的事件无法移除,因为传入的是一个匿名函数
二、ie6-ie8中,使用attachEvent()绑定多个事件的倒序执行问题。
var oBtn = document.getElementById('btn');
oBtn.attachEvent('onclick',function(){
alert(1)
})
oBtn.attachEvent('onclick',function(){
alert(2)
})
oBtn.attachEvent('onclick',function(){
alert(3)
})
//ie9+ 下执行顺序1、2、3
//ie6-ie8下执行顺序3、2、1
解决问题
我想写一个跨浏览器的事件绑定模块,这样以后可以复用,同时我想解决上诉问题。JQuery内部使用事件队列和数据缓存机制解决此问题,看了下相关源码,实在复杂,自个试了一些方法,勉强实现。贴段代码,原来是用面向对象写的,不想让人看得很复杂,所有改成函数来组织。
/*绑定事件的接口
*
*@param {dom-DOM}和{type-string}和{fn-function} 可选参数{fnName-string}
*@execute 创建事件队列,添加到DOM对象属性上,
将事件处理程序(函数)加入事件队列
可为事件处理程序添加一个标识符,用于删除指定事件处理程序
*/
function bind(dom,type,fn,fnName){
dom.eventQueue = dom.eventQueue || {};
dom.eventQueue[type] = dom.eventQueue[type] || {};
dom.handler = dom.handler || {};
if (!fnName) {
var index = queueLength(dom,type);
dom.eventQueue[type]['fnQueue'+index] = fn;
}
else {
dom.eventQueue[type][fnName] = fn;
};
if (!dom.handler[type]) bindEvent(dom,type);
};
/*绑定事件
*
*@param {dom-DOM}和{type-string}
*@execute 只绑定一次事件,handler用于遍历执行事件队列中的事件处理程序(函数)
*@caller bind()
*/
function bindEvent(dom,type){
dom.handler[type] = function(){
for(var guid in dom.eventQueue[type]){
dom.eventQueue[type][guid].call(dom);
}
};
if (window.addEventListener) {
dom.addEventListener(type,dom.handler[type],false);
}
else {
dom.attachEvent('on'+type,dom.handler[type]);
};
};
/*移除事件的接口
*
*@param {dom-DOM}和{type-string} 可选参数{fnName-function}
*@execute 如果没有标识符,则执行unBindEvent()
如果有标识符,则删除指定事件处理程序,如果事件队列长度为0,执行unBindEvent()
*/
function unBind(dom,type,fnName){
var hasQueue = dom.eventQueue && dom.eventQueue[type];
if (!hasQueue) return;
if (!fnName) {
unBindEvent(dom,type)
}
else {
delete dom.eventQueue[type][fnName];
if (queueLength(dom,type) == 0) unBindEvent(dom,type);
};
};
/*移除事件
*
*@param {dom-DOM}和{type-string}
*@execute 移除绑定的事件处理程序handler,并清空事件队列
*@caller unBind()
*/
function unBindEvent(dom,type){
if (window.removeEventListener) {
dom.removeEventListener(type,dom.handler[type])
}
else {
dom.detachEvent(type,dom.handler[type])
}
delete dom.eventQueue[type];
};
/*判断事件队列长度
*
*@param {dom-DOM}和{type-string}
*@caller bind() unBind()
*/
function queueLength(dom,type){
var index = 0;
for (var length in dom.eventQueue[type]){
index++ ;
}
return index;
};
使用方法
var oBtn = document.getElementById('btn');
//绑定事件
//为button同时绑定三个click事件函数
//ie6-ie8下执行顺序不变
bind(oBtn,'click',function(){
alert(1);
})
bind(oBtn,'click',function(){
alert(2);
},'myFn')
bind(oBtn,'click',function(){
alert(3);
})
//移除事件
//移除所有绑定的click事件函数,支持移除匿名函数
unBind(oBtn,'click')
//只移除标识符为myfn的事件函数
unBind(oBtn,'click','myFn')
程序思路
程序主要思路就像将事件队列作为dom元素对象的一个属性,添加在dom元素上,而不会污染全局环境,这样可以解决不同dom元素绑定不同事件类型的多个事件函数的数据存储问题。
//dom元素上的事件队列
dom{
eventQueue : {
'click' : {
fnQueue1 : function,
myfn : function,
fnQueue3 : function
}
'mouseover' : {
fnQueue1 : function,
fnQueue2 : function
}
}
}
每次先把事件函数添加到对应事件类型的事件队列中,只绑定一次事件。触发事件时执行handler事件函数,handler则遍历执行事件队列中的事件函数。
unBind()如果没有传入标识符,则移除所有绑定的事件函数,支持移除匿名函数,如果有标识符则移除指定的事件函数。
程序逻辑并不复杂,可能有bug和性能问题,有兴趣可以指导交流下。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

JavaScript是一种广泛应用于Web开发的编程语言,而WebSocket则是一种用于实时通信的网络协议。结合二者的强大功能,我们可以打造一个高效的实时图像处理系统。本文将介绍如何利用JavaScript和WebSocket来实现这个系统,并提供具体的代码示例。首先,我们需要明确实时图像处理系统的需求和目标。假设我们有一个摄像头设备,可以采集实时的图像数
