javascript的事件触发器介绍的实现

事件触发器从字面意思上可以很好的理解,就是用来触发事件的,但是有些没有用过的朋友可能就会迷惑了,事件不是通常都由用户在页面上的实际操作来触发的吗?这个观点不完全正确,因为有些事件必须由程序来实现,如自定义事件,jQuery的ajax框架的一些自定义事件就必须由事件触发器来实现。当然,在一些特殊情况下,用事件触发器来触发事件比用户的实际操作来触发事件更方便。

对于实现事件触发器,浏览器都有原生的方法来支持,但是在兼容性上又有很大的出入,这种兼容性的问题完全在意料之中,IE有自己的方法,其他标准浏览器也有一套方法,不说谁的方法好与不好,对于WEB开发者来说搞出几套方法就是对开发人员的一种折磨。IE支持fireEvent方法来实现事件触发,标准浏览器支持dispatchEvent来实现事件触发,两面派的IE9是两者都支持。下面是出自prototype.js的源码(其实我是从司徒正美的博客复制过来的):

代码如下:

var fireEvent = function(element,event){
 if (document.createEventObject){
  // IE浏览器支持fireEvent方法
  var evt = document.createEventObject();
  return element.fireEvent('on'+event,evt)
 }
 else{
  // 其他标准浏览器使用dispatchEvent方法
  var evt = document.createEvent( 'HTMLEvents' );
  // initEvent接受3个参数:
  // 事件类型,是否冒泡,是否阻止浏览器的默认行为
  evt.initEvent(event, true, true); 
  return !element.dispatchEvent(evt);
 }
};

上面的方法可以兼容主流的浏览器以实现事件触发器的功能。但是对于一些封装好的事件处理系统,如jQuery的event模块,就没这么简单了,只能通过模拟来实现了。我在之前写过一个很简单的事件处理系统,最近又碰到自定义事件的需求,于是在之前的事件系统的基础上模拟了一个事件触发器,代码如下:


代码如下:

/**
 * 事件触发器
 * @param { Object } DOM元素
 * @param { String / Object } 事件类型 / event对象
 * @param { Array }  传递给事件处理函数的附加参数
 * @param { Boolean } 是否冒泡
 */
trigger : function( elem, event, data, isStopPropagation ){
 var type = event.type || event,
  // 冒泡的父元素,一直到document、window
  parent = elem.parentNode ||
   elem.ownerDocument ||
   elem === elem.ownerDocument && win,
  eventHandler = $.data( elem, type + 'Handler' );

isStopPropagation = typeof data === 'boolean' ?
  data : (isStopPropagation || false);

data = data && isArray( data ) ? data : [];

// 创建自定义的event对象  
 event = typeof event === 'object' ?
  event : {
   type : type,
   preventDefault : noop,
   stopPropagation : function(){
    isStopPropagation = true;
   }
  };

event.target = elem;  
 data.unshift( event );
 if( eventHandler ){
  eventHandler.call( elem, data );
 }
 // 递归调用自身来模拟冒泡
 if( parent && !isStopPropagation ){
  data.shift();
  this.trigger( parent, event, data );
 }
}

模拟的原理并不难,给某元素绑定一个事件处理函数,如果有触发事件的实际操作就会执行相应的事件处理函数,所以要达到事件触发器的功能只要获取到相应的事件处理函数然后执行就差不多了,这是最基本的。

在实际的事件发生时浏览器会生成一个event对象,里面包含了一些事件发生时的属性和信息。如果没有实际的事件发生是没有这个event对象的,所以上面的代码也创建了一个event对象满足最基本的功能。

还有事件冒泡,如果没有实际的事件发生,自然也不会有冒泡的行为,那么如果要模拟冒泡的功能,就必须不断的查找父元素并检查是否绑定了相同类型的事件,直至到document和window为止,如果结构复杂,这种递归调用的方法性能估计会不怎么样。

最后是浏览器的默认行为,我觉得这个要去模拟相当麻烦,麻烦到不知如何去实现,比如a标签默认的跳转,我测试了jQuery的trigger,也没有实现,但是一些其他的行为貌似又在API手册中有介绍。毕竟这个功能不是很重要,暂时也没做过多的深究。

(0)

相关推荐

  • javascript中的事件代理初探

    事件在javascript中一直是最强大的对象之一.javascript提供了addEventListener和attachEvent两个方法来为DOM节点绑定事件,jquery作了进一步封装,提供了兼容各个浏览器的bind方法.现在来看,这种传统的事件绑定方式存在着以下不足: 1.可能需要绑定很多的EventHander. 假如页面中某个表有100行,现在必须为每一行绑定一个click事件.那么就必须绑定100个EventHandler,这对页面性能来说有着极大的负担,因为需要创建更多的内存来

  • 封装了一个支持匿名函数的Javascript事件监听器

    关于js中的事件监听大家用的比较多了,无非是判断浏览器是否支持addEventListener和attachEvent,网上搜索关于事件监听的方法也挺多,但是总有些不是很完善.下面的方法中对于添加事件监听的方法是一样的,只不过在取消事件绑定上面做了点手术,现在可以支持匿名函数的使用,所以在绑定事件的时候不再需要给函数单独命名了. 主要代码: 复制代码 代码如下: /*绑定事件与取消绑定*/var handleHash = {};var bind = (function() { if (windo

  • javaScript 页面自动加载事件详解

    方法1: 复制代码 代码如下: Window.onload=function(){   Var name=document.getElementById("name").val();//加载HTML,并且加载外部所有所有的引用文件(图片,css样式,js等)} 方法2:需要引入Jquery的 .js文件 复制代码 代码如下: $(document).ready(function(){         alert("JQuery的第一个入门案例");//加载HTML,

  • javascript页面加载完执行事件代码

    复制代码 代码如下: <script type="text/javascript" language="JavaScript"> //: 判断网页是否加载完成                 document.onreadystatechange = function () {                    if(document.readyState=="complete") {                       

  • javascript监听鼠标滚轮事件浅析

    我们都见到过这些效果,用鼠标滚轮实现某个表单内的数字增加减少操作,或者滚轮控制某个按钮的左右,上下滚动.这些都是通过js对鼠标滚轮的事件监听来实现的.今天这里介绍的是一点简单的js对于鼠标滚轮事件的监听. 不同浏览器不同的事件 首先,不同的浏览器有不同的滚轮事件.主要是有两种,onmousewheel(firefox不支持)和DOMMouseScroll(只有firefox支持),关于这两个事件这里不做详述,想要了解的朋友请移步:鼠标滚轮(mousewheel)和DOMMouseScroll事件

  • JavaScript控制各种浏览器全屏模式的方法、属性和事件介绍

    复制代码 代码如下: // 判断各种浏览器,找到正确的方法function launchFullscreen(element) {  if(element.requestFullscreen) {    element.requestFullscreen();  } else if(element.mozRequestFullScreen) {    element.mozRequestFullScreen();  } else if(element.webkitRequestFullscree

  • JavaScript函数获取事件源的小例子

    复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv=&qu

  • javascript的事件触发器介绍的实现

    事件触发器从字面意思上可以很好的理解,就是用来触发事件的,但是有些没有用过的朋友可能就会迷惑了,事件不是通常都由用户在页面上的实际操作来触发的吗?这个观点不完全正确,因为有些事件必须由程序来实现,如自定义事件,jQuery的ajax框架的一些自定义事件就必须由事件触发器来实现.当然,在一些特殊情况下,用事件触发器来触发事件比用户的实际操作来触发事件更方便. 对于实现事件触发器,浏览器都有原生的方法来支持,但是在兼容性上又有很大的出入,这种兼容性的问题完全在意料之中,IE有自己的方法,其他标准浏览

  • 莱鸟介绍javascript onclick事件

    onclick事件的定义和用法: 当点击对象的时候会触发此事件. 浏览器支持: 1.IE浏览器支持此事件. 2.火狐浏览器支持此事件. 3.Opera浏览器支持此事件. 4.谷歌浏览器支持此事件. 5.safria浏览器支持此事件. 实例代码: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"/> <meta name="author" content=&qu

  • JavaScript执行机制详细介绍

    目录 1.进程与线程的概念 2.浏览器原理 3.同步与异步 4.执行栈与任务队列 5.事件循环(Event-Loop) 6.定时器 前言: 不论是工作还是面试,我们可能都经常会碰到需要知道代码的执行顺序的场景,所以打算花点时间彻底搞懂JavaScript的执行机制. 想要搞懂JavaScript执行机制,你需要清楚下面这些知识: (以浏览器环境为例,与Node环境不同) 1.进程与线程的概念 浏览器原理 事件循环(Event-Loop),任务队列(同步任务,异步任务,微任务,宏任务) 进程与线程

  • 全面解析jQuery $(document).ready()和JavaScript onload事件

    对元素的操作和事件的绑定需要等待一个合适的时机,可以看下面的例子: <!DOCTYPE html> <meta charset="utf-8"> <html> <head> <title>1-1</title> <script type="text/javascript"> document.getElementById("panel").onclick = fu

  • JavaScript 与 Java 区别介绍 学java怎么样

    java和javascript长得是如此地相像,那么它们是一回事儿吗?现在让我来揭晓答案吧! JavaScript 是一种嵌入式脚本文件,直接插入网页,有浏览器一边解释一边执行. java 语言不一样,他必须在JAVA虚拟机上运行.而且事先需要进行编译. JAVA的语法规则比JavaScript要严格的多,功能要强大的多. 首先,这两个家伙没有任何的血缘关系,java是是由Sun 公司于1995年5月推出的,而javascript是于1995年由Netscape公司设计实现而成的,由于Netsc

  • 从Node.js事件触发器到Vue自定义事件的深入讲解

    Node.js中的事件触发器所引发的思考 今天在看 Node.js 文档的时候讲到事件触发器,其中的 emit 方法让我想到了 Vue 中的自定义事件,借此我对 Vue 又有了新的理解,所以将我的理解记录下来,留作学习笔记. Node.js中的事件触发器 Node.js 为我们提供了一个事件模块:EventEmitter,我们可以用它来处理事件 const EventEmitter = require('events') const eventEmitter = new EventEmitter

  • JavaScript之事件循环案例讲解

    js中的事件循环 因为JavaScript是单线程的,同一事件只能执行一种方法,所以会将程序中的方法加入到执行栈中按照后进先出的顺序依次执行,当遇见异步任务时不会被阻塞,而是将任务放入事件队列中,继续执行执行栈中的同步代码,等当前执行栈中的所有任务都执行完毕则查找事件队列中的任务,并把任务的回调函数放入执行栈中,执行其中的同步代码,如此反复形成的循环被称为事件循环. node.js node.js特点 事件驱动 从上向下执行代码,当遇到需要回调的地方就加入到事件队列中,主线程运行完就去执行事件队

  • JavaScript中事件冒泡机制示例详析

    什么是冒泡? DOM事件流(event  flow )存在三个阶段:事件捕获阶段. 处于目标阶段. 事件冒泡阶段. 事件捕获(event  capturing):通俗的理解就是,当鼠标点击或者触发dom事件时,浏览器会从根节点开始由外到内进行事件传播,即点击了子元素,如果父元素通过事件捕获方式注册了对应的事件的话,会先触发父元素绑定的事件. 事件冒泡(dubbed  bubbling):与事件捕获恰恰相反,事件冒泡顺序是由内到外进行事件传播,直到根节点. dom标准事件流的触发的先后顺序为:先捕

  • JavaScript 鼠标事件(MouseEvent)案例讲解

    鼠标事件-MouseEvent 当鼠标进行某种操作时,就会生成一个event对象,该对象记录着鼠标触发事件时的所有属性. 可以通过如下方法在google控制台打印出 MouseEvent 对象. function mouseDown(e){ var e = e||event; console.log(e) } window.onload = function (){ document.getElementsByTagName('body')[0].addEventListener('moused

  • 深入理解JavaScript的事件执行机制

    目录 前言 浏览器 JS 异步执行的原理 浏览器中的事件循环 执行栈与任务队列 宏任务和微任务 Async/await的运行顺序 特点 示例 个人分析 前言 熟悉事件循环,了解浏览器运行机制将对我们理解 JavaScript 的执行过程和排查运行问题有很大帮助.以下是总结的一些浏览器事件循环的一些原理和示例. 浏览器 JS 异步执行的原理 JS 是单线程的,也就是同一个时刻只能做一件事情,那么,为什么浏览器可以同时执行异步任务呢? 因为浏览器是多线程的,当 JS 需要执行异步任务时,浏览器会另外

随机推荐