最近在使用Bootstrap.js,一不小心趴开源码看了一下,尤其是看到tab.js

 var hideEvent = $.Event('hide.bs.tab', {
relatedTarget: $this[0]
}) var showEvent = $.Event('show.bs.tab', {
relatedTarget: $previous[0]
}) $previous.trigger(hideEvent)
$this.trigger(showEvent)

看到这里的时候,顿时一头雾水!然后立马去查了jquery的官方API(http://api.jquery.com/category/events/event-object/),发现原来jQuery.Event 构造器暴露出来,然后通过$.trigger来触发,然后来了个简单的例子

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>$.Event</title>
<script src="http://libs.baidu.com/jquery/1.10.2/jquery.js"></script>
</head>
<body>
<input type="text" id="input-1" />
<script>
$(function(){
var e = jQuery.Event( "keydown",{name:65});
$("#input-1").on("keydown",function(event){
console.log(event.name);//初始化的时候输出 65 ,以后每次keydown都是undefined
})
$( "#input-1" ).trigger( e );
})
</script>
</body>
</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,我们仿造其原理制作如下函数

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>$.Event</title>
<script src="http://libs.baidu.com/jquery/1.10.2/jquery.js"></script>
</head>
<body>
<input type="text" id="input-1" />
<script>
+function($){
function testEvent(){
var hidden = jQuery.Event( "hide.bs",{
user:"foo",
pass:"bar",
relatedTarget: $("#input-1")[0]
});
$( "#input-1" ).trigger(hidden);
}
$("#input-1").on("click",testEvent);
}(jQuery)
$(function(){
$( "#input-1" ).on("hide.bs",function(event){
alert(event.relatedTarget.tagName)//INPOUT
alert(event.user)//foo
})
})
</script>
</body>
</html>

  事实证明$.Event在自定义函数上面有很强大的 功能存在,通过relatedTarget来指向对应事件的目标DOM元素,如果你看了bootstrap的tab的案例,瞬间就会觉得此功能作用甚大,可是不经间发现了transition.js中对于$.Event的用法让人大吃一惊,在原生js中有handleEvent(IE9+支持)

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>js Handler 事件</title>
</head>
<body>
<button id="btn-1">点击执行click事件</button>
<input type="text" id="input-1" />
<script type="text/javascript">
var Events={
handleEvent: function(event) {
switch (event.type) {
case "click":
this.clickEvent(event);
break;
case "focus":
this.focusEvent(event);
break;
}
},
clickEvent:function(){
alert("执行了click的事件");
},
focusEvent:function(){
alert("执行了focus的事件");
}
}
if(window.addEventListener){
document.getElementById("btn-1").addEventListener("click",Events,false);
document.getElementById("input-1").addEventListener("focus",Events,false);
}
</script>
</body>
</html>

  同样作为大名鼎鼎的jquery,一定也实现了这种方式,果不其然,在transtion.js中可以看到赤裸裸的如何实现这样的方式,同样我们按照transtion.js做了一个精简来执行下面函数

 <!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>handlerEvent</title>
<script src="http://libs.baidu.com/jquery/1.11.1/jquery.js"></script>
<link rel="stylesheet" type="text/css" href="../dist/css/bootstrap.css">
</head> <body>
<button id="btn-1">按钮-1</button>
<script type="text/javascript">
(function($) {
function transitionEnd() {
var el = document.createElement('bootstrap')
var transEndEventNames = {
WebkitTransition: 'webkitTransitionEnd',
MozTransition: 'transitionend',
OTransition: 'oTransitionEnd otransitionend',
transition: 'transitionend'
}
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return {
end: transEndEventNames[name]
}
}
}
return false // explicit for ie8 ( ._.)
}
$.fn.emulateTransitionEnd = function(duration) {
$(this).one('bsTransitionEnd', function() {
alert("执行one('bsTransitionEnd')自定义事件");
})
//在webkit的条件下$.support.transition.end=webkitTransitionEnd
$(this).trigger($.support.transition.end) }
$(function() {
$.support.transition = transitionEnd();
if (!$.support.transition) return;
$.event.special.bsTransitionEnd = {
bindType: $.support.transition.end,
delegateType: $.support.transition.end,
handle: function(e) {
if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
}
}
})
})(jQuery)
$(function(){
$("#btn-1").emulateTransitionEnd();
}) </script>
</body> </html>

  通过$.event.special.bsTransitionEnd的方式来查找对应执行函数,这个其实就是原声js 的 handleEvent的jQuery实现方式!有时候一个点就可以带出一个面!

随机推荐

  1. struts2 <s:iterator> 遍历方法

    1.MapAction.java import java.util.ArrayList;   import java.util.HashMap;   import java.util.List;    ...

  2. C++ 常见容器

    迭代器. 基本介绍(来源于网络):迭代器是一种抽象的概念.能够遍历容器内的 部分/全部 元素.每个迭代器中包含着元素的地址.  它可以将 抽象容器 和 泛型算法 结合起来.   大致原理: 1)迭代器 ...

  3. chapter 1 Number/Adventurous Person

    part1: 1- Which would be easier to remember a munber or a name? Well, I am better at remembering num ...

  4. Win7 64位 php+Apache+mysql 配置

    注明:此文转载至 http://www.cnblogs.com/isyouth/p/3778045.html 一 :准备阶段 1:php php下载链接:http://windows.php.net/ ...

  5. 【python学习笔记02】python的数据类型2

    列表和元组之间的主要区别是:列表括在括号([])和它们的元素和大小是可以改变的,而元组在圆括号(),不能被更新.元组可以被认为是只读列表. 存储在一个列表中的值可以使用切片操作符来访问([]和[:]) ...

  6. Mvc中使用MvcSiteMapProvider实现站点地图之基础篇

    MvcSiteMapProvider 是针对 ASP.NET MVC 中,提供菜单. 网站地图. 站点地图路径功能,以及更多的工具.它提供配置使用一个可插入的体系结构,可以是 XML. 数据库或动态生 ...

  7. SQL Server 查看正在运行的事务信息的 2 种方法。

    方法 1.sys.dm_tran_session_transactions; 方法 2.dbcc opentran ------------------------------------------ ...

  8. 再次优化NGINX+php-fpm上传

    上次写了一篇nginx+php-fpm优化上传,一位博友留言介绍了,第三方nginx upload module http://www.grid.net.ru/nginx/upload.en.html ...

  9. SQL Server数据库空间管理 (2)

     本篇内容主要解决剩余的两个问题:2).日志文件不停增长  4).自动增长和自动收缩 日志文件不停增长的解决 首先,当日志文件超过预期的时候,我们然要看看日志文件中存放了什么内容:DBCC LOG ; ...

  10. table的样式定义

    table的cellpadding和cellpadding我们经常会用如下的方式来清除默认样式: <table cellspacing="0" cellpadding=&qu ...