最近在使用Bootstrap.js,一不小心趴开源码看了一下,尤其是看到tab.js
1 var hideEvent = $.Event(‘hide.bs.tab‘, { 2 relatedTarget: $this[0] 3 }) 4 5 var showEvent = $.Event(‘show.bs.tab‘, { 6 relatedTarget: $previous[0] 7 }) 8 9 $previous.trigger(hideEvent) 10 $this.trigger(showEvent)
看到这里的时候,顿时一头雾水!然后立马去查了jquery的官方API(http://api.jquery.com/category/events/event-object/),发现原来jQuery.Event 构造器暴露出来,然后通过$.trigger来触发,然后来了个简单的例子
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>$.Event</title> 6 <script src="http://libs.baidu.com/jquery/1.10.2/jquery.js"></script> 7 </head> 8 <body> 9 <input type="text" id="input-1" /> 10 <script> 11 $(function(){ 12 var e = jQuery.Event( "keydown",{name:65}); 13 $("#input-1").on("keydown",function(event){ 14 console.log(event.name);//初始化的时候输出 65 ,以后每次keydown都是undefined 15 }) 16 $( "#input-1" ).trigger( e ); 17 }) 18 </script> 19 </body> 20 </html>
虽然keydown事件中event.name明显是不存在,但是我们通过$.Eevent依然可以输出值65,也就是$.Event通过trigger默认触发事件把属性name绑定到keydown的事件,所以页面加载的时候就输出65,如果你此刻再去对input进行keydown 就显示undefined,根据jQuery官网翻译知道传入的参数的参数可以根据事件的情况而变化,可以是altKey, bubbles, button, cancelable, charCode, clientX, clientY, ctrlKey, currentTarget, data, detail, eventPhase, metaKey, offsetX, offsetY, originalTarget, pageX, pageY, relatedTarget, screenX, screenY, shiftKey, target, view, which
同样我们来拆解bootstrap中tab.js,我们仿造其原理制作如下函数
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>$.Event</title> 6 <script src="http://libs.baidu.com/jquery/1.10.2/jquery.js"></script> 7 </head> 8 <body> 9 <input type="text" id="input-1" /> 10 <script> 11 +function($){ 12 function testEvent(){ 13 var hidden = jQuery.Event( "hide.bs",{ 14 user:"foo", 15 pass:"bar", 16 relatedTarget: $("#input-1")[0] 17 }); 18 $( "#input-1" ).trigger(hidden); 19 } 20 $("#input-1").on("click",testEvent); 21 }(jQuery) 22 $(function(){ 23 $( "#input-1" ).on("hide.bs",function(event){ 24 alert(event.relatedTarget.tagName)//INPOUT 25 alert(event.user)//foo 26 }) 27 }) 28 </script> 29 </body> 30 </html>
事实证明$.Event在自定义函数上面有很强大的 功能存在,通过relatedTarget来指向对应事件的目标DOM元素,如果你看了bootstrap的tab的案例,瞬间就会觉得此功能作用甚大,可是不经间发现了transition.js中对于$.Event的用法让人大吃一惊,在原生js中有handleEvent(IE9+支持)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>js Handler 事件</title> 6 </head> 7 <body> 8 <button id="btn-1">点击执行click事件</button> 9 <input type="text" id="input-1" /> 10 <script type="text/javascript"> 11 var Events={ 12 handleEvent: function(event) { 13 switch (event.type) { 14 case "click": 15 this.clickEvent(event); 16 break; 17 case "focus": 18 this.focusEvent(event); 19 break; 20 } 21 }, 22 clickEvent:function(){ 23 alert("执行了click的事件"); 24 }, 25 focusEvent:function(){ 26 alert("执行了focus的事件"); 27 } 28 } 29 if(window.addEventListener){ 30 document.getElementById("btn-1").addEventListener("click",Events,false); 31 document.getElementById("input-1").addEventListener("focus",Events,false); 32 } 33 </script> 34 </body> 35 </html>
同样作为大名鼎鼎的jquery,一定也实现了这种方式,果不其然,在transtion.js中可以看到赤裸裸的如何实现这样的方式,同样我们按照transtion.js做了一个精简来执行下面函数
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>handlerEvent</title> 7 <script src="http://libs.baidu.com/jquery/1.11.1/jquery.js"></script> 8 <link rel="stylesheet" type="text/css" href="../dist/css/bootstrap.css"> 9 </head> 10 11 <body> 12 <button id="btn-1">按钮-1</button> 13 <script type="text/javascript"> 14 (function($) { 15 function transitionEnd() { 16 var el = document.createElement(‘bootstrap‘) 17 var transEndEventNames = { 18 WebkitTransition: ‘webkitTransitionEnd‘, 19 MozTransition: ‘transitionend‘, 20 OTransition: ‘oTransitionEnd otransitionend‘, 21 transition: ‘transitionend‘ 22 } 23 for (var name in transEndEventNames) { 24 if (el.style[name] !== undefined) { 25 return { 26 end: transEndEventNames[name] 27 } 28 } 29 } 30 return false // explicit for ie8 ( ._.) 31 } 32 $.fn.emulateTransitionEnd = function(duration) { 33 $(this).one(‘bsTransitionEnd‘, function() { 34 alert("执行one(‘bsTransitionEnd‘)自定义事件"); 35 }) 36 //在webkit的条件下$.support.transition.end=webkitTransitionEnd 37 $(this).trigger($.support.transition.end) 38 39 } 40 $(function() { 41 $.support.transition = transitionEnd(); 42 if (!$.support.transition) return; 43 $.event.special.bsTransitionEnd = { 44 bindType: $.support.transition.end, 45 delegateType: $.support.transition.end, 46 handle: function(e) { 47 if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) 48 } 49 } 50 }) 51 })(jQuery) 52 $(function(){ 53 $("#btn-1").emulateTransitionEnd(); 54 }) 55 56 57 58 </script> 59 </body> 60 61 </html>
通过$.event.special.bsTransitionEnd的方式来查找对应执行函数,这个其实就是原声js 的 handleEvent的jQuery实现方式!有时候一个点就可以带出一个面!