首页 web前端 js教程 javascript 跨浏览器的事件系统_javascript技巧

javascript 跨浏览器的事件系统_javascript技巧

May 16, 2016 pm 06:31 PM
javascript 事件系统

但实质上javascript之父也不能主宰这一切,他支持的网景也没有强大到让竞争对手乖乖地使用它的产品,微软搞了一个JScript,死去的Macromedia 搞了一个ActionScript,还有更多,听说这个分支挺复杂的。但借用浏览器内置的DOM事件模型,第一个后果是,想使用它就必须借助某个DOM对象,window,document或元素节点,第二个后果是由于每个浏览器对DOM的支持不一,不能确保事件模型的一致,第三个是由于基于DOM对象,很容易造成循环引用。微软打赢第一次浏览器战争后,就基本没有更新其DOM模型了,与不断更新向w3c,ecma等标准靠近的“标准浏览器”分成两大阵营。但标准浏览器内也不是磐石一块,如FF就不支持mousewheel而是DOMMouseScroll,opera的contextmenu 是不可控的。我们需要自己实现一下。眼下,双主都实现DOM2的事件模型,微软的是attachEvent为首,标准的是addeventListener,允许同一个元素可以绑定多个同类型的事件回调函数。网上许多addEvent函数都是用它们做成的,但也不可靠,首先,IE的回调函数没有强制绑定事件对象,而标准浏览器是强舞曲第一个参数即为事件对象,尽管我们可以用call函数实现强制绑定,但IE的事件对象与标准的也不一样,这里有许多工作要做。另一个,就是回调函数的执行顺序问题,IE是无规则的,标准是按绑定的先后顺序执行。因此,这两个函数也被否定。我打算用最原始的onXXXX来实现,绑定多个函数时,就把它们放入一个函数中,一个for循环搞定。

复制代码 代码如下:

;

<头>
<元字符集=“utf-8”/>
;
活动系统 by 司徒正美 <br> <br>#target{ <br>宽度:400px; <br>高度:100px; <br>背景:蓝色; <br>} <br></风格> <br> <br>var dom = {}; <br>Array.prototype.indexOf = function (el, index) { <br>var n = this.length>>>0, <br>i = index == null ? 0:索引for (; i if (i in this && this[i] === el) return i; <br>返回-1; <br>}; <br>//http://msdn.microsoft.com/zh-cn/library/bb383786.aspx <br>//删除 Array 对象中某个元素的第一个匹配项。 <br>Array.prototype .remove= function (item) { <br>var index = this.indexOf(item); <br>if (index !== -1) return this.removeAt(index); <br>返回空; <br>}; <br>// 移除 Array 对象中指定位置的元素。 <br>Array.prototype.removeAt= function (index) { <br>return this.splice(index, 1) <br>}; <br>dom.attachEvent = function(el, type, handler) { <br>// 在每个元素上设置一个对象类型的私有属性事件 <br>if (!el.events) el.events = { }; <br>//该对象有许多键为事件类型,实现函数备份的属性<br>var handlers = el.events[type]; <br>if (!handlers) { <br>handlers = el.events[type] = []; <br>// 如果它本来就是以onXXXX的方式绑定了某个事件,那么就把它置为事件内存的第一个元素 <br>if (el["on" type]) { <br>handlers[0 ] = el[“on”类型]; <br>} <br>} <br>//添加回调函数 <br>handlers.push(handler) <br>//以onXXXX方式绑定我们的处理函数 <br>el["on" type] = dom.handleEvent; <br>}; <br>dom.detachEvent = function(el, type, handler) { <br>if (el.events && el.events[type]) { <br>el.events[type].remove(handler) <br> } <br>} <br>dom.handleEvent = function (event) { <br>var returnValue = true; <br>// 获取事件对象(IE 使用全局事件对象) <br>event = event || fixEvent(((this.ownerDocument || this.document || this).parentWindow || window).event); <br>// 获取事件处理程序哈希表的引用 <br>var handlers = this.events[event.type]; <br>// 执行每个事件处理程序 <br>for(var i=0,n=handlers.length;i<n>if (handlers[i](event) === false) { <br>返回值 = false; <br>} <br>} <br>返回 returnValue; <br>}; <br>function fixEvent(event) { <br>// 添加 W3C 标准事件方法 <br>event.preventDefault = fixEvent.preventDefault; <br>event.stopPropagation = fixEvent.stopPropagation; <br>返回事件; <br>}; <br>fixEvent.preventDefault = function() { <br>this.returnValue = false; <br>}; <br>fixEvent.stopPropagation = function() { <br>this.cancelBubble = true; <br>}; <br>var $ = function(id){ <br>返回 document.getElementById(id) <br>} <br>window.onload = function(){ <br>var a = function(e){ <br> $("p").innerHTML = e.clientX " " e.clientY <br>} <br>dom.attachEvent($("target"),"mousemove",a); <br>setTimeout(function(){ <br>dom.detachEvent($("target"),"mousemove",a); <br>},10*1000) <br>} <br> ; <br></头> <br><身体> <br><div id="target"> <br></div> <br><p id="p"></p> <br></身体> <br></html> <br> </div> <br>我们回顾一下上面的流程,这个事件系统其实是Dean大神的addEvent的一个改版。 <br>设置一个作为命名空间的对象。 <br>对Array做一些扩展。 <br>attachEvent 函数用于绑定事件。具体做法在需要绑定事件的对象设置一个events属性,里面再按事件类型放置回调函数,由于有时我们可能在同一个元素上绑定2个或多个onclick事件什么的,因此它们必须是一个数组。最后用DOM0的原始方法添加一个onXXXX属性。 <br>detachEvent 函数用于卸载事件,就是把events上对应类型的数组元素去掉。 <br>handleEvent 执行回调函数。我们以onXXXX的形式绑定了一个全局的函数,它的作用是获得与修正事件对象,然后取得此事件类型对应的所有回调函数,然后依次把事件对象作为它们的第一个参数再执行它们。最后是处理一下冒泡。 <br>fixEvent 修正事件对象。基本上就是让IE拥有标准浏览器的两个方法。 <br>对于一般应用,它已够用了。但如果追求完全。我们还有许多东西都要用。首先把events这个庞大的对象放到元素上是非常不妥的,不利于集中管理。二,fixEvent并不彻底,如target,pageX/Y等标准浏览器下的属性,在IE中还是用不了。 <br>首先是handleEvent 函数,现在是无论标准浏览器还是IE的事件对象都要修正,还在每次调用时为IE修正其currentTarget 值。 <br><div class="codetitle"> <span><a style="CURSOR: pointer" data="43857" class="copybut" id="copybut43857" onclick="doCopy('code43857')"><u>复制代码</u></a></span> 代码如下:</div> <div class="codebody" id="code43857"> <br>dom.handleEvent = function (event) { <br>event = event || window.event <br>event = dom.fixEvent(event); <br>event.currentTarget = this;//修正currentTarget <br>var returnValue = true; <br>var handlers = this.events[event.type]; <br>for(var i=0,n=handlers.length;i<n;i ){ <br>if (handlers[i](event) === false) { <br>returnValue = false; <br>} <br>} <br>return returnValue; <br>}; <br> </div> <br>在我们介绍的新版fixEvent函数时,我们先隆重介绍我从jQuery剽窃过来的伪事件对象。 <br><div class="codetitle"> <span><a style="CURSOR: pointer" data="83378" class="copybut" id="copybut83378" onclick="doCopy('code83378')"><u>复制代码</u></a></span> 代码如下:</div> <div class="codebody" id="code83378"> <br>dom.oneObject = function(arr,val){ <br>var result = {},value = val !== undefined ?值:1; <br>for(var i=0,n=arr.length;i<n>结果[arr[i]] = value; <br>返回结果; <br>}; <br>dom.mixin = function(result, source) { <br>if (arguments.length === 1) { <br>source = result; <br>结果= dom; <br>} <br>if (result && source ){ <br>for(var key in source) <br>source.hasOwnProperty(key) && (result[key] = source[key]); <br>} <br>if(arguments.length > 2 ){ <br>var other = [].slice.call(arguments,2); <br>for(var i=0,n=others.length;i<n>result = argument.callee(result,others[i]); <br>} <br>} <br>返回结果; <br>} <br>var MouseEventOne = dom.oneObject(["click","dblclick","mousedown", <br>"mousemove","mouseout", "mouseover","mouseup"],"[object鼠标事件]"); <br>var HTMLEventOne = dom.oneObject(["中止","模糊","更改","错误","焦点", <br>"加载","重置","调整大小","滚动", "选择","提交","卸载"],"[对象事件]"); <br>var KeyboardEventOne = dom.oneObject(["keyup","keydown","keypress",], <br>"[object KeyboardEvent]"); <br>var EventMap = dom.mixin({},MouseEventOne,HTMLEventOne,KeyboardEventOne) <br>var fn = "prototype"; <br>dom.Event = function( src ) { <br>if ( !this.preventDefault ) { <br>return new dom.Event[fn].init( src ); <br>} <br>}; <br>函数 returnFalse() { <br>返回 false; <br>} <br>函数 returnTrue() { <br>返回 true; <br>} <br>// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html <br>dom.Event[fn ] = { <br>init:function(src){ <br>//如果建立是事件对象 <br>if ( src && src.type ) { <br>this.originalEvent = src; <br>this.type = src.type; <br>//如果确定的是事件类型 <br>} else { <br>this.type = src; <br>} <br>this.timeStamp = new Date().valueOf(); <br>this["expando"] = true; <br>}, <br>//http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/events.html#Conformance <br>toString:function(){ <br>返回EventMap[this.type] || "[对象事件]" <br>}, <br>preventDefault: function() { <br>this.isDefaultPrevented = returnTrue; <br>var e = this.originalEvent; <br>if ( !e ) { <br>返回; <br>} <br>// 如果存在preventDefault 现在就调用它 <br>if ( e.preventDefault ) { <br>e.preventDefault(); <br>} <br>// 如果存在returnValue 现在就将其设置为false <br>e.returnValue = false; <br>}, <br>stopPropagation: function() { <br>this.isPropagationStopped = returnTrue; <br>var e = this.originalEvent; <br>if ( !e ) { <br>返回; <br>} <br>// 如果存在preventDefault 现在就调用它 <br>if ( e.stopPropagation ) { <br>e.stopPropagation(); <br>} <br>// 如果存在returnValue 现在就将其设为true <br>e.cancelBubble = true; <br>}, <br>stopImmediatePropagation: function() { <br>this.isImmediatePropagationStopped = returnTrue; <br>this.stopPropagation(); <br>}, <br>isDefaultPrevented: returnFalse, <br>isPropagationStopped: returnFalse, <br>isImmediatePropagationStopped: returnFalse <br>}; <br>dom.Event[fn].init[fn] = dom.Event[fn]; <br></n></n> </div> <br>这个构造函数只实现了W3C事件模型的少量方法,属性那些去了哪?不急,我们在fixEvent方法中通过复制的方式实现它们。为了区别事件对象伪与事件对象,我们在上面添加了一个expando属性。<br><div class="codetitle"> <span><a style="CURSOR: pointer" data="64815" class="copybut" id="copybut64815" onclick="doCopy('code64815')"><u>复制代码</u></a></span>代码如下:</div> <div class="codebody" id="code64815"> <br>var buttonMap = { <br>1:1, <br>4:2, <br>2:3 <br>} <br>dom.fixEvent = function(event){ <br>if ( event[ "expando" ] ) { <br>return event; <br>} <br>var originalEvent = event <br>event = dom.Event(originalEvent); <br>for(var prop in originalEvent){ <br>if(typeof originalEvent[prop] !== "function"){ <br>event[prop] = originalEvent[prop] <br>} <br>} <br>//如果不存在target属性,为它添加一个 <br>if ( !event.target ) { <br>event.target = event.srcElement || document; <br>} <br>//如果事件源对象为文本节点,则置入其父元素 <br>if ( event.target.nodeType === 3 ) { <br>event.target = event.target.parentNode; <br>} <br>//如果不存在relatedTarget属性,为它添加一个 <br>if ( !event.relatedTarget && event.fromElement ) { <br>event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; <br>} <br>//如果不存在pageX/Y则结合clientX/Y做一双出来 <br>if ( event.pageX == null && event.clientX != null ) { <br>var doc = document.documentElement, body = document.body; <br>event.pageX = event.clientX (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); <br>event.pageY = event.clientY (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); <br>} <br>// 为键盘事件添加which事件 <br>if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) { <br>event.which = event.charCode || event.keyCode; <br>} <br>// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) <br>if ( !event.metaKey && event.ctrlKey ) { <br>event.metaKey = event.ctrlKey; <br>} <br>// 判定鼠标事件按下的是哪个键,1 === left; 2 === middle; 3 === right <br>if ( !event.which && event.button !== undefined ) { <br>event.which = buttonMap[event.button] <br>} <br>return event; <br>} <br> </div> <br>毫不犹豫地抄jQuery的方法,因为在所有类库中,jQuery的方法是最好提取的。 <br>现在我们基本解决了文章中段提出的两个问题中的其中一个。要解决第一个我们就需要引入缓存系统了。这个留在下一部分讲。 <br><div class="htmlarea"> <textarea id="runcode6959"> <meta charset="utf-8"> <meta content="IE=8" http-equiv="X-UA-Compatible"> <title>Event by 司徒正美

显示鼠标位置

请按下键盘的键
[Ctrl A 全选 注:如需引入外部Js需刷新才能执行
]
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

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

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

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

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

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

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

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

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

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

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

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

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

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

javascript中如何使用insertBefore javascript中如何使用insertBefore Nov 24, 2023 am 11:56 AM

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

JavaScript和WebSocket:打造高效的实时图像处理系统 JavaScript和WebSocket:打造高效的实时图像处理系统 Dec 17, 2023 am 08:41 AM

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

See all articles