js 高级应用 自定义事件
Javascript与浏览器交互的途径主要是事件的形式。事件是一种观察者的设计模式,对象可以发布时间,然后其它对象可以观察该对象,等待这些时刻到来并通过运行代码来响应。
观察者模式主要由主体和观察者组成。主体负责发布事件,同时观察者通过订阅这些事件来观察该主体。该模式的一个关键概念是主体并不知道观察者的任何事情,也就是说它可以独自存在并正常运行即使观察者不存在。从另一方面来讲观察者知道主体并能注册事件的回调函数(事件处理程序)。
事件是与DOM交互的最常用的方式,但也可以用于非DOM的代码中—通过实现自定义事件。自定义事件的机制其实就是创建一个可以管理事件的对象。让其他对象监听那些事件。
1 function EventTarget(){ 2 this.handles={}; 3 } 4 EventTarget.prototype = { 5 constructor: EventTarget, 6 addHandler:function(type,fn){ 7 if(!(this.handles[type] instanceof Array)){ 8 this.handles[type] = []; 9 } 10 this.handles[type].push(fn); 11 }, 12 fire:function(event){ 13 if(!event.target){ 14 event.target = this; 15 } 16 if(this.handles[event.type] instanceof Array){ 17 var handles = this.handles[event.type]; 18 for(var i=0,len=handles.length;i<len;i++){ 19 handles[i](event); 20 } 21 } 22 }, 23 removeHandler:function(type,fn){ 24 if (this.handles[type] instanceof Array) { 25 var handles = this.handles[type]; 26 for (var i =0,len = handles.length;i<len;i++) { 27 if(handles[i] == fn){ 28 break; 29 } 30 }; 31 handles.splice(i,1); 32 }; 33 } 34 }
EventTarget有一个单独的属性,用于储存事件处理程序,三个方法中,addHandler用于添加事件处理程序,将事件添加到相应的事件型号的数组下,用push添加到数组的最后。removeHandler用于移除相应的事件。fire用于触发相应事件类型下的所有事件,通过for的形式循环触发。
要使用这个自定义事件类型,可以通过以下这个方式。
1 function Person(name){ 2 this.name = name; 3 this.etarget = new EventTarget(); 4 } 5 Person.prototype = { 6 constructor:Person, 7 say:function(message){ 8 this.etarget.fire({type:'message',target:this,message:message}); 9 }, 10 addMess:this.addMess = function(type,fn){ 11 this.etarget.addHandler(type,fn); 12 } 13 }
这样就可以做到事件监听机制的使用了。在这里,一旦调用say方法,便触发了事件,它包含了事件的细节。同时在其中fire不是公开调用的,这段代码可以按以下方式使用。
1 var person = new Person('Tom'); 2 person.addMess('message',function(event){ 3 console.log(event.target.name+'says:'+event.message); 4 }) 5 person.say('hello!!!');
EXAMPLE:拖放
拖放是一种常见的用户界面模式,在HTML5中也有类似的API实现了该功能,在这里我们会用javascript和html来实现这个功能。
拖放的核心函数调用就是mousemove了,通过鼠标移动不断触发,并不断调整位置,实现拖动的连续性。
1 var Dragdrop = (function(){ 2 var dragging = null; 3 dragHandler = function(event){ 4 var event = event||window.event, 5 target = event.target ||event.srcElement; 6 switch(event.type){ 7 case 'mousedown': 8 if(target.className.indexOf('draggable') > -1){ 9 dragging = target; 10 } 11 break; 12 case 'mousemove': 13 if(dragging != null){ 14 dragging.style.left = event.pageX+'px'; 15 dragging.style.top = event.pageY+'px'; 16 } 17 break; 18 case 'mouseup': 19 dragging = null; 20 break; 21 } 22 }; 23 return {enable : function(){ 24 document.addEventListener('mouseup',dragHandler,false); 25 document.addEventListener('mousemove',dragHandler,false); 26 document.addEventListener('mousedown',dragHandler,false); 27 }, 28 disable: function(){ 29 document.removeEventListener('mouseup',dragHandler,false); 30 document.removeEventListener('mousemove',dragHandler,false); 31 document.removeEventListener('mousedown',dragHandler,false); 32 }} 33 })();
现在还不能实现真正的交互,因为我们无法知道到底什么时候开始拖动,拖动结束。这时就可以用自定义事件来指示这个事件的发生。实现方式主要是先创建一个新的EventTarget的对象,然后添加enable和disable方法,最后返回这个对象:
1 var Dragdrop = (function(){ 2 var dragEvent = new EventTarget(), 3 dragging = null; 4 dragHandler = function(event){ 5 var event = event||window.event, 6 target = event.target ||event.srcElement; 7 switch(event.type){ 8 case 'mousedown': 9 if(target.className.indexOf('draggable') > -1){ 10 dragging = target; 11 dragEvent.fire({target:dragging,type:'dragstart'}); 12 } 13 break; 14 case 'mousemove': 15 if(dragging != null){ 16 dragging.style.left = event.pageX+'px'; 17 dragging.style.top = event.pageY+'px'; 18 dragEvent.fire({target:dragging,type:'dragmove',pos:{left:event.pageX,top:event.pageY}}); 19 } 20 break; 21 case 'mouseup': 22 dragging = null; 23 dragEvent.fire({target:dragging,type:'dragstop'}); 24 break; 25 } 26 }; 27 dragEvent.enable = function(){ 28 document.addEventListener('mouseup',dragHandler,false); 29 document.addEventListener('mousemove',dragHandler,false); 30 document.addEventListener('mousedown',dragHandler,false); 31 }; 32 dragEvent.disable = function(){ 33 document.removeEventListener('mouseup',dragHandler,false); 34 document.removeEventListener('mousemove',dragHandler,false); 35 document.removeEventListener('mousedown',dragHandler,false); 36 }; 37 return dragEvent; 38 })();
在对代码的主要改动处都以特殊的字体标出来了,这些改动使得Dragdrop对象支持了事件,使用方式如下:
1 Dragdrop.addHandler('dragstart',function(event){ 2 console.log('drag start!'); 3 }); 4 Dragdrop.addHandler('dragmove',function(event){ 5 console.log('dragmove,pos:'+event.pos.left+':'+event.pos.top); 6 }); 7 Dragdrop.addHandler('dragstop',function(event){ 8 console.log('dragstop'); 9 });
这样就死的Dragdrop对象更加健壮了,就可以处理一下复杂的拖放事件了。
所有代码集合如下:
<html> <head><script type="text/javascript">function EventTarget(){this.handles={};}EventTarget.prototype = {constructor: EventTarget,addHandler:function(type,fn){if(!(this.handles[type] instanceof Array)){this.handles[type] = [];}this.handles[type].push(fn);},fire:function(event){if(!event.target){event.target = this;}if(this.handles[event.type] instanceof Array){var handles = this.handles[event.type];for(var i=0,len=handles.length;i<len;i++){handles[i](event);}}},removeHandler:function(type,fn){if (this.handles[type] instanceof Array) {var handles = this.handles[type];for (var i =0,len = handles.length;i<len;i++) {if(handles[i] == fn){break;}};handles.splice(i,1);};}}var Dragdrop = (function(){var dragEvent = new EventTarget(),dragging = null;dragHandler = function(event){var event = event||window.event,target = event.target ||event.srcElement;switch(event.type){case 'mousedown':if(target.className.indexOf('draggable') > -1){dragging = target;dragEvent.fire({target:dragging,type:'dragstart'});}break;case 'mousemove':if(dragging != null){dragging.style.left = event.pageX+'px';dragging.style.top = event.pageY+'px';dragEvent.fire({target:dragging,type:'dragmove',pos:{left:event.pageX,top:event.pageY}});}break;case 'mouseup':dragging = null;dragEvent.fire({target:dragging,type:'dragstop'});break;}};dragEvent.enable = function(){document.addEventListener('mouseup',dragHandler,false);document.addEventListener('mousemove',dragHandler,false);document.addEventListener('mousedown',dragHandler,false);};dragEvent.disable = function(){document.removeEventListener('mouseup',dragHandler,false);document.removeEventListener('mousemove',dragHandler,false);document.removeEventListener('mousedown',dragHandler,false);};return dragEvent;})();/*function Person(name){this.name = name;this.etarget = new EventTarget();}Person.prototype = {constructor:Person,say:function(message){this.etarget.fire({type:'message',target:this,message:message});},addMess:this.addMess = function(type,fn){this.etarget.addHandler(type,fn);}}var person = new Person('Tom');person.addMess('message',function(event){console.log(event.target.name+'says:'+event.message);})person.say('hello!!!');*/Dragdrop.addHandler('dragstart',function(event){console.log('drag start!');});Dragdrop.addHandler('dragmove',function(event){console.log('dragmove,pos:'+event.pos.left+':'+event.pos.top);});Dragdrop.addHandler('dragstop',function(event){console.log('dragstop');});</script> </head> <body><div class="draggable" style="position:absolute;width:100px;height:100px;background:silver"></div> </body> </html>
View Code
转载于:https://www.cnblogs.com/cyITtech/p/3566897.html
js 高级应用 自定义事件相关推荐
- 【JS】512- JS 自定义事件如此简单!
在前端开发世界中,JavaScript 和 HTML 之间往往通过 事件 来实现交互.其中多数为内置事件,本文主要介绍 JS自定义事件概念和实现方式,并结合案例详细分析自定义事件的原理.功能.应用及注 ...
- JS高级程序设计笔记——事件(一)
一.事件流 假设有如下HTML代码: <!DOCTYPE html> <html> <head><title>Event</title> & ...
- html 自定义js,js 自定义事件
js怎么自定义事件,并能让用on事件监听 你这个问题全部内容应该是如下吧: 在视频播放的时候,能够用on监听事件的触发,如下: player.on('pause',function(){ consol ...
- 使用 JS 关闭警告框及监听自定义事件(amaze ui)
使用 JS 关闭警告框及监听自定义事件(amaze ui) 一.总结 1.jquery匿名函数:第8行,jquery匿名函数,$(function(){});,有没有很简单,只是少了jquery的前面 ...
- html 自动触发 事件,js自动触发事件自定义事件
在有些情况下,我们需要程序逻辑自动触发元素的事件,例如js提供了click(), form提供了reset(),submit()等方法!在jquery中提供了trigger()方法帮助我们自动触发事件 ...
- vue中 点击事件的写法_vue中的事件:原生事件与自定义事件__Vue.js
模板编译 processAttrs 对于ast attributes处理(v-on/@) 利用onRE与dirRE来捕获事件 这里最重要的就是dynamic的判断,vue中可以用动态参数来命名事件名称 ...
- Node.js: 如何继承 events 自定义事件及触发函数
events 是node.js的核心api ,几乎大部分node.js 的api都继承 events 类(javascript中没有类,也不存在继承,确切说是模拟类和继承,点击查看) 比如我们常见的 ...
- Js高级(1) 事件11.30
JS高级(1) 1.事件 概念:浏览器客户端上客户触发的行为都称为事件,所有的事件都是天生自带的,不需要我们去绑定,只需要我们去触发.通过obj.事件名=function(){} 事件名:onmous ...
- JS基础-事件模型(事件事件流自定义事件事件冒泡/代理)
文章目录 一.事件与事件流 二.事件模型 1.DOM0级模型 2.IE事件模型 3.DOM2级模型 4.DOM3级事件处理方式 三.事件对象 四.事件绑定与解除 1.事件绑定 1.1对象.on事件名字 ...
最新文章
- java中二维数组求最大值代码。。。。。。不懂呀
- Android开发之2048安卓版
- kafak消费者从头开始消费(消费者组)
- VS工程切换cuda版本
- Java中的weak reference 和 soft reference
- php无限极,PHP无限极分类
- ajax跨域请求 html5,HTML5中使用postMessage实现Ajax跨域请求的方法
- import org.eclipse.californium.scandium.DTLSConnector;
- 谈薪资被 HR 怼了:估计你一辈子就是个程序员!气不过啊。。。
- Spark入门案例--出租车数据分析
- STM32驱动SPI FLASH(W25Q64)
- 郭盛华:互联网安全可能是下一个热门投资主题
- 语音识别/合成开源项目
- JavaScript中canvas绘制太极图案
- Windows Live Writer插件开发
- Java中对中国标准时间进行格式化(yyyy-MM-dd HH:mm:ss)两种方法
- 【Linux系统编程】进程地址空间和虚拟地址空间
- 如何学习3DMAX建模放样?
- Linux限制cpu睿频限制频率
- python考试报名费用_计算机python二级考试报名
热门文章
- LeetCode 914. 卡牌分组
- simpledateformat格式_大厂都是怎么用Java8代替SimpleDateFormat?
- 怎么查看电脑有没有python_使用python获取电脑的磁盘信息方法
- Jenkins分布式构建和部署(master-slave)
- ITester软件测试小栈长期持续在线征集
- SQL从入门到入魔之初入门
- 【Twitter】时序图神经网络
- Filecoin Gas基础费率降至0.23 nanoFIL
- Staked 回应节点遭到 slash 惩罚:由技术性问题导致,将全额赔偿受影响客户
- 1月20日到期的5.2万美元比特币期权数量超1万份