`
jljlpch
  • 浏览: 319498 次
  • 性别: Icon_minigender_1
  • 来自: 南昌
社区版块
存档分类
最新评论

jquery event trigger 分析

阅读更多
6.2.2 trigger
                    prk/彭仁夔  08-08-26
注册了事件,如onclick。那么当用户点击这个元素时,就会自动触发这个事件的已经注册的事件处理函数。但是我们有的时候要采用程序来模拟事件的触发就得采用强迫触发某个事件。在IE中我们可以采用.fireEvent()来实现。如:<form onsubmit="a()" >中,如果button的form.submit()的方式提交表单,是不会主动触发onsumbit事件的,如果必须的话,就要在submit前$(“:form”)[0].fireEvent("onsubmit”,),这样就会触发该事件。
在mozilla中有三个步骤:    var   evt   =   document.createEvent('HTMLEvents');
 evt.initEvent('change',true,true);    t.dispatchEvent(  evt );
在prototype是采用这样的方式来实现的。那么jquery中呢,它的实现方式有一点不一样。
trigger : function(type, data, fn) {
return this.each(function() {
		jQuery.event.trigger(type, data, this, true, fn);
			});	},
Trigger有三个参数,data参数是为了注册的事件函数提供了实传。如果data[0]中preventDefault存在,data[0]就可以做为用户自定义的包裹事件的空间。Fn是可以为事件提供一个即时即用的事件处理方法。也就是在没有注册事件的情况下也可以通过传入处理函数来处理事件。如果已经注册了,那就是在原来的事件处理函数之后执行。
  	//这个方法将会触发指定的事件类型上所有绑定的处理函数。但不会执行浏览器默认动作.
triggerHandler : function(type, data, fn) {
return this[0]&& jQuery.event.trigger(type,data,this[0],false,fn);
	},
triggerHandle通过把jQuery.event.trigger的donative参数设为false,来阻止执行浏览器默处理方法。它与trigger不现的一点,还在于它只是处理jquery对象的第一个元素。
上面两个方法都调用了jQuery.event.trigger来完成任务:
trigger : function(type, data, elem, donative, extra) {
	data = jQuery.makeArray(data);//data可以为{xx:yy}
    //支持getData!这样的形式,exclusive = true表现会对add的注册的
	//事件的所有函数进行命名空间的分种类的来执行。
if (type.indexOf("!") >= 0) {                         ①
		type = type.slice(0, -1);var exclusive = true;
		}
if (!elem) {// 处理全局的fire事件                       ②
	if (this.global[type])
		jQuery.each(jQuery.cache, function() {
		  // 从cache中找到所有注册该事件的元素,触发改事件的处理函数
			if (this.events && this.events[type])
				jQuery.event.trigger(type, data, this.handle.elem);
			});
	} else {// 处理单个元素事件的fire事件                    ③
	 if (elem.nodeType == 3 || elem.nodeType == 8)	return undefined;
      var val, ret, fn = jQuery.isFunction(elem[type] || null),
	 // 如果data参数传进入的不是浏览器的event对象的话,event变量为true.
	//如果data参数本身是娄组,那么第一个元素不是浏览器的event对象时为true.
	//对于event为true。即没有event传进入,先构建一个伪造的event对象存在data[0]。
	event = !data[0] || !data[0].preventDefault;
    	// 在没有传入event对象的情况下,构建伪造event对象。
	if (event) {//存到数组中的第一个                          ④
		data.unshift( { type : type,target : elem,
	         preventDefault : function() {},stopPropagation : 
function() {}, timeStamp : now()	});
	   data[0][expando] = true; // 不需要修正伪造的event对象
		}
	 data[0].type = type; //防止事件名出错
	//表现会进行事件注册函数的分类(命名空间)执行。不是所有的。
	 if (exclusive) data[0].exclusive = true;

	//与prototype等传统的处理方式不一样,没有采用fireEvent来
	//来fire通过注册到浏览器事件中的事件处理方法。
	//这里分了三步,先fire通过jQuery.event.add来注册的事件,这个事件
	//有可能是自定义的事件(没有注册到浏览器事件中)。
	//第二步是fire通过elem.onclick方式注册的事件的本地处理函数
     //第三步是fire默认的事件处理方式(在本地的onclick的方式注册
	 //不存在的情况下)。	
	
// 这里是触发通过jQuery.event.add来注册的事件,
	  var handle = jQuery.data(elem, "handle");            ⑤
	  if (handle)val = handle.apply(elem, data); //这里data分成多个参数
	//处理触发通过elem.onfoo=function()这样的注册本地处理方法,
	//但是是对于links 's .click()不触发,这个不会执行通过addEvent
	//方式注册的事件处理方式。			
	if ((!fn || (jQuery.nodeName(elem, 'a') && type == "click")) ⑥
		&& elem["on"+ type]&& elem["on"+type].apply(elem,data) === false)
	  val = false;
//额外的函数参数的开始几个是通过data给定的。这里会把伪造加上的event给去掉。
//它的最后一个参数是一系列的事件处理函数返回的结果,一般为bool值
//这个函数可以根据这个结果来处理一个扫尾的工作。
	if (event)	data.shift();
// 处理触发extra给定的函数处理。
	if (extra && jQuery.isFunction(extra)) {                     ⑦
		 ret = extra.apply(elem, val == null ? data : data.concat(val));
		 //如果这个函数有返回值,那么trigger的返回值就是它的返回值
		 //没有的话就是串连的事件处理函数的最后一个返回值。一般为bool
		if (ret !== undefined)	val = ret;
	 }
	// 触发默认本地事件方法,它是在没有如.onclick注册事件
	//加上前面的执行事件处理函数返回值都不为false的情况下,才会执行。
	//它还可以通donative来控制是否执行。
	//如form中可以采用this.submit()来提交form.
	if (fn && donative !== false && val !== false          ⑧
				&& !(jQuery.nodeName(elem, 'a') && type == "click")) {
		this.triggered = true;
		try {elem[type]();	//对于一些hidden的元素,IE会报错
			} catch (e) {}
		}
	this.triggered = false;
	}
return val;
},
Jquery的fire事件的方法与prototype中实现是完全不一样的。Ext、YUI没有提供强迫触发事件的方法。对于一般的思维,程序来触发浏览器的事件就应该采用fireEvent或dispatchEvent方法来运行。
但是jquery采用一种不同的方法。对于通过jquery.event.add来注册的事件(不管是自定义的还是注册到浏览器事件),它保存在一个与元素及事件名相对应的cache中。在浏览器的触发中,这个是没有什么作用。但是它是为了通过等程序来强迫触发时,从cache中取到对应的事件处理函数。这个时候就抛开了浏览器的事件。在这里还可以执行一些自定义的事件函数。如⑤处。
对于通过html的标签中如click或elem.onclick=function(){}形式注册的事件函数。在⑥处它采用执行元素的如onclick形式的回调函数就可以。通过这种dom0的方式只能注册一个函数。
有的时候,如果没有onclick这样的事件处理函数,浏览器会执行默认的处理函数。如form.submit()。⑧处可以看出对于这样的默认的事件处理,还可以通过参数donative来控制。
程序手动强迫触发事件,有一点问题就是event是怎么生成,就是没有浏览器生成event传入到函数中。Prototype采用了是新生成的dataavailable的事件。这样的事件也没有什么作用。Jquery也采用fake的方式伪造一个一个事件,如④,它比prototype的事件好处在于它能通过trigger的函数的参数来传入需要的event。Prototype则不能。
通过上面的分析,隐隐可以看出Jquery是通过模拟浏览器的触发事件的执行过程来构建这个trigger的函数的。先执行dom1方式(addEvent)注册的事件,再执行dom0方式注册的事件,最后看看要不要执行默认的事件处理。
在⑦处,我们可以看出trigger还可能通过传入回调函数和参数来完成对执行的事件处理函数的结果进行判断处理,形成新结果通过trigger的函数返回。这在有的时候是很有用的。
除了这些,它还能对于事件的处理函数进行分类(namespace),可以在合适的时候调用事件的不同分类的的处理函数(通过jquery.event.add来注册)。这个分类的处理在handle实现。
	handle : function(event) {
		// 返回 undefined or false
		var val, ret, namespace, all, handlers;
       //修改了传入的参数,这里是引用。
		event = arguments[0] = jQuery.event.fix(event || window.event);
		// 命名空间处理
		namespace = event.type.split(".");
		event.type = namespace[0];
		namespace = namespace[1];
		// all = true 表明任何 handler,namespace不存在,同时
		//event.exclusive不存在或为假时,all=true.
		all = !namespace && !event.exclusive;
		// 找到元素的events中缓存的事件名的处理函数列表
		handlers = (jQuery.data(this, "events") || {})[event.type];
		for (var j in handlers) {// 每个处理函数执行
			var handler = handlers[j];
			// Filter the functions by class
			if (all || handler.type == namespace) {
				// 传入引用,为了之后删除它们
				event.handler = handler;
				event.data = handler.data;//add的时候加上的
				ret = handler.apply(this, arguments);// 执行事件处理函数
			    if (val !== false)
				   val = ret;// 只要有一个处理函数返回false,本函数就返回false.
				if (ret === false) {// 不执行浏览器默认的动作
					event.preventDefault();
					event.stopPropagation();
				}
			}
		}
		return val;	},
handle的主要功能是就是分类且有序地执行事件的所有的注册的处理函数。

 

分享到:
评论
2 楼 huazai_wow 2013-09-03  
  楼主  你只是分析了 在jquery 中 有使用到 jQuery.event.trigger  方法的区别和
和分析这些情况啊。
楼主 能不能问你一个问题啊.在使用 ajaxfileupload.js 中 使用 jQuery.event.trigger
这个方法会在什么时候执行例如:  jQuery.event.trigger("ajaxSend", [xml, s]);  这样的方法会在什么时候执行 。楼主方便的话 写个例子 给我啊 谢谢!
   QQ 邮箱: 2598059791@qq.com
    
1 楼 zlssy 2009-03-09  
不错,呵呵  学习!

相关推荐

    jQuery.event.trigger()的简单解释

    今天小编就为大家分享一篇关于jQuery.event.trigger()的简单解释,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

    jQuery源码分析之Event事件分析

    对于事件的操作无非是addEvent,fireEvent,removeEvent这三个事 件方法。... Jquery提供了一个 event的包裹,这个相对于其它的lib提供的有点简单,但是足够使用。 代码如下: //对事件进行包裹。 fix : function(e

    jQuery trigger()方法用法介绍

    jQuery的trigger()方法用法介绍: 此方法可以触发匹配元素上指定类型的事件。 它具有两种语法格式,下面就分别做一下介绍。 语法结构一: 代码如下: $(selector).trigger(event,[param1,param2,…]) 参数解析: 1....

    jquery中trigger()无法触发hover事件的解决方法

    今天做一个项目,遇到了一个问题,是以前没有遇到过的,就此记上一笔。 1、trigger方法解释 ...其中eventType包含javascript内置的事件、jQuery增加的事件和自定义事件。例如: $('#foo').bind('click', f

    jQuery 1.5 API 中文版

    $.trigger( event [, data]) obj.triggerHandler( event [, data]) $.delegate( selector, type, [data], handler) $.undelegate( [selector, type, [handler]]) Live Events $.live( eventType [, data], fn() ) $....

    读jQuery之十 事件模块概述

    后面会详细分析jQuery.event.add/jQuery.event.remove/jQuery.event.trigger。 虽然事件模块代码很难读,但其提供的API接口还是很清晰的。如下 1 添加事件(bind/one/live/delegate/hover/toggle) bind 基本的添加...

    jQuery拖放插件Draggabilly.zip

    // return true to trigger an event listener just once draggie.on( 'dragMove', function() { console.log('Draggabilly did move, just once'); return true; }); 标签:Draggabilly

    jQuery详细教程

    Event 函数 绑定函数至 $(document).ready(function) 将函数绑定到文档的就绪事件(当文档完成加载时) $(selector).click(function) 触发或将函数绑定到被选元素的点击事件 $(selector).dblclick(function) 触发或...

    jQuery实现自定义事件的方法

    $event.trigger("myEventName"); 自定义事件绑定 下面的代码创建了一个绑定到自定义事件和自定义事件触发时将被执行。 $(this).bind("myEventName",function(){ alert&#40;"myEventName triggered"&#41;;

    jquery下为Event handler传递动态参数的代码

    [removed] (function($) { //demo1 $(“#demo”).bind(“demo-trigger”, function(e, args) { var info = []; //对应的我们从args参数中获取数据 for(var prop in args) { info.push(prop + “:” + args[prop]); ...

    Jquery阻止事件冒泡 event.stopPropagation

    version added: 1.0event.stopPropagation() 我们可以用 event.isPropagationStopped() 来确定这个方法是否(在那个事件对象上)调用过了。 这个方法对 trigger() 来自定义的事件同样有效。 注意,这不会阻止同一个...

    ajaxfileupload+springmvc例子

    handleError: function( s, xhr, status, e ) { // If a local callback was specified, fire it if ( s.error ) { ... jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] ); } },

    ajaxfileupload.js(异步上传文件插件)

    jquery的一款异步文件上传插件,我博客中有关于此插件的详细教程。 handleError: function( s, xhr, status, e ) { ... jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] ); } },

    Jquery 自定义事件实现发布/订阅的简单实例

    $.event.trigger(logoff);//广播一个事件 [removed] = logoff.php;//导航到新页面 }); 以上这篇Jquery 自定义事件实现发布/订阅的简单实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多...

    ajaxupload

    1.修复之前存在的一些bug, 2.修复了对ie的兼容, 3.增加了对jquery10的兼容 handleError: function (s, xhr, status, e) { ... jQuery(s.context) : jQuery.event).trigger("ajaxError", [xhr, s, e]); } },

    jQuery中triggerHandler()方法用法实例

    具体分析如下: 此方法触发被选元素的指定事件类型。 从上面定义可以看出此方法和trigger()方法功能上很类似,但还是有巨大区别。以下是主要区别: 1.此方法不会触发浏览器默认事件。 2.此方法触发jQuery对象集合中第...

    jquery需要的所有js文件

    d=d||{},c=a.Event(c),c.type=(b===this.widgetEventPrefix?b:this.widgetEventPrefix+b).toLowerCase(),c.target=this.element[0],f=c.originalEvent;if(f)for(e in f)e in c||(c[e]=f[e]);this.element.trigger(c,...

    jQuery检查事件是否触发的方法

    $('button').click(function(event, wasTriggered) { if (wasTriggered) { alert&#40;'triggered in code'&#41;; } else { alert&#40;'triggered by mouse'&#41;; } }); $('button').trigger('click', true); ...

    jquery按回车键实现表单提交的简单实例

    本文章在给大家介绍在用户输入完信息之后直接按回车进行表单提交的jquery实现方法,有需要了解的朋友可进来参考以。 键盘事件有3: jquery键盘事件参考: 1、keydown() keydown事件会在键盘按... $(#submit).trigger

    jQuery中on方法使用注意事项详解

    传入事件处理函数的data需要在事件绑定时就确定好,不同于trigger(‘eventType’,[data]),tirgger方法中传入的data(对象或数组形式)是事件发生时才计算的值。 如果同一个事件处理程序被多次绑定给同一个元素,...

Global site tag (gtag.js) - Google Analytics