JQuery 支持 hide 和 show 事件的方法与分析
问题提出
JQuery不支持hide和show作为事件形式出现, 实际上这两个仅仅是JQuery对象的一个方法(fn);
有一类UI交互需求,根据一个DOM对象的或者显示对附属的DOM对象做相同操作,
一般情况下, 利用jquery hide和show方法的扩展参数中的回调函数,是可以实现的,例如:
$( "#book" ).hide( "slow", function() {
$( "#booklet" ).hide()
});
如果附属DOM是一个动态生成的插件,则在主DOM的hide中处理附DOM的隐藏, 就破坏了动态生成插件的灵活性,
因为需要让使用对象(主DOM)自行添加同步显示和隐藏代码。例如 每一篇随笔的 TAG 可以自己输入,
也可以从历史记录中选择, 这个选择插件就属于动态生成的, 如果在某种交互条件下,需要隐藏掉 TAG,
须要使用 hide 的回调函数处理。
解决方法
如果jq支持hide和show可以设置事件,并且在hide()和show()调用的时候被触发,
类似一般的click事件绑定和触发, 则可以解决此问题(插件来设置其目标DOM的hide和show事件,
完成自身的显示隐藏,而不是目标在hide方法中完成,这样只需要在插件的HTML中设置目标ID即可)。
但是在jq官网上没有找到hide作为事件,实施上确实没有,
应该是这个不是常规事件, 不是由用户能够触发的,故没有涉及为事件,可以理解为动作。
在网上找到前辈的足迹, 并且找到解决方案。
http://stackoverflow.com/questions/2857900/onhide-type-event-in-jquery
http://jsfiddle.net/mofle/eZ4X3/
查看jsfiddle有例子,只需要扩展一下JQ框架
(function($) {
$.each(['show','hide'], function(i, val) {
var _org = $.fn[val];
$.fn[val] = function() {
this.trigger(val);
return _org.apply(this, arguments);
};
});
})(jQuery);
方法分析
上面的方法是对JQ框架实现hide和show方法的扩展, 我们来看下JQ是怎么实现这两个方法的:
jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
var cssFn = jQuery.fn[ name ];
jQuery.fn[ name ] = function( speed, easing, callback ) {
return speed == null || typeof speed === "boolean" ?
cssFn.apply( this, arguments ) :
this.animate( genFx( name, true ), speed, easing, callback );
};
});
看样是都是跟fn有关, 上面提供的解决方案相当于对 JQ fn的做了继承,
除了 保证原有fn内容(函数)执行 (return _org.apply(this, arguments);),
还增加了 对 hide 和 show 事件的触发(this.trigger(val);)。
fn与$()获得的对象
那么, fn 到底是什么东西? 跟 $()获得的JQ对象有什么关系?
还是要从刀勒符说起, 首先 $ == JQuery 的, 然后$就是一个函数, 函数内容如下:
// Define a local copy of jQuery
jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init( selector, context );
},
这样使用$符号获取的 JQuery对象, 实际就是 构造函数 jQuery.fn.init new出来的对象,
jQuery.fn.init 此函数定义如下, 其中this表示new出来的对象, 可以看出为 array 形式的对象,
然后, init == jQuery.fn.init , new jQuery.fn.init == new init,
故$()对象继承了init.prototype, 即 我们刚开始关注的 jQuery.fn, 这样, fn中任何函数,
对于$()对象都可以直接调用 即 $().hide();
init = jQuery.fn.init = function( selector, context ) {
...... return jQuery.makeArray( selector, this );
}; // Give the init function the jQuery prototype for later instantiation
init.prototype = jQuery.fn;
事件与trigger
那么为什么 bind("hide", function(e){}) 的事件 hide , 可以被 this.trigger("hide"); 触发调用,
这其中又有哪些道道?
bind 间接调用on, on与bind一样同为 jQuery.fn 的一个函数, 可以被$()对象调用,
on调用实际上执行, 是对$()对象数组中的每一个DOM元素 调用了 jQuery.event.add
bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},
jQuery.fn.extend({ on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
.......
return this.each( function() {
jQuery.event.add( this, types, fn, data, selector );
});
},
从下面的代码轨迹, 看出 bind 将新的事件对象(handleObj)存入了 DOM 对象(elem)的 events[ type ]
jQuery._data( elem ).events[ type ]
jQuery.event = { global: {}, add: function( elem, types, handler, data, selector ) {
var tmp, events, t, handleObjIn,
special, eventHandle, handleObj,
handlers, type, namespaces, origType,
elemData = jQuery._data( elem );
...... // Init the element's event structure and main handler, if this is the first
if ( !(events = elemData.events) ) {
events = elemData.events = {};
}
.......
// Init the event handler queue if we're the first
if ( !(handlers = events[ type ]) ) {
handlers = events[ type ] = [];
handlers.delegateCount = 0;
........
} ....... // Add to the element's handler list, delegates in front
if ( selector ) {
handlers.splice( handlers.delegateCount++, 0, handleObj );
} else {
handlers.push( handleObj );
}
.......
同样 trigger fn也是从 jQuery._data( elem ).events[ type ] 获取 当前事件的 处理函数 handle, 然后handle在当前对象上执行。
trigger: function( event, data, elem, onlyHandlers ) {
var handle, ontype, cur,
bubbleType, special, tmp, i,
eventPath = [ elem || document ],
type = hasOwn.call( event, "type" ) ? event.type : event,
namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; cur = tmp = elem = elem || document;
........
// jQuery handler
handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
if ( handle ) {
handle.apply( cur, data );
}
.........
问题解决代码
阴影部分为“插件"代码, 可以单独裁减掉, 而不修改 first div控件原有代码。
<html>
<head>
<title>Example</title>
<script type="text/javascript" src="./jquery.js"></script>
</head>
<body> <div id="first" style="width:100px; height:100px; background: green">first</div>
<div id="second" style="width:100px; height:100px; background: yellow" targetDOMID="first">second</div> <input type="button" value="show first" id="showFirst"/>
<input type="button" value="hide first" id="hideFirst"/> <script type="text/javascript">
(function($) {
$.each(['show','hide'], function(i, val) {
var _org = $.fn[val];
$.fn[val] = function() {
this.trigger(val);
return _org.apply(this, arguments);
};
});
})(jQuery); /* 插件DOM, 给目标DOM(第一个div)添加 隐藏/显示 事件,
事件触发后, 第二个div也隐藏/显示 */
var targetDOMID = $("#second").attr("targetDOMID");
var targetDOM = $("#"+targetDOMID);
targetDOM.bind("hide", function(){
$("#second").hide();
})
.bind("show", function(){
$("#second").show();
}); /* 按钮click事件触发 第一块div 的显示和隐藏fn */
$("#showFirst").click(function(){
$("#first").show();
})
$("#hideFirst").click(function(){
$("#first").hide();
}) </script> </body>
</html>
JQuery 支持 hide 和 show 事件的方法与分析的更多相关文章
- jquery中交替点击事件toggle方法的使用示例
jquery中交替点击事件toggle方法中有两个参数,分别是要交替执行的事件.如果不传参默认是显示隐藏功能,下面有个不错的示例,感兴趣的朋友可以参考下 复制代码代码如下: $('#clickId‘) ...
- jQuery文本框(input textare)事件绑定方法教程
jquery 的事件绑定已经用on替换了原来的bind,接下来为大家分享下bind的使用方法及input textare事件.目前1.7以上,jquery?的事件绑定已经用on替换了原来的bind,接 ...
- jQuery中的事件绑定方法
在jQuery中,事件绑定方法大致有四种:bind(),live(), delegate(),和on(). 那么在工作中应该如何选择呢?首先要了解四种方法的区别和各自的特点. 在了解这些之前,首先要知 ...
- jquery技巧之让任何组件都支持类似DOM的事件管理
本文介绍一个jquery的小技巧,能让任意组件对象都能支持类似DOM的事件管理,也就是说除了派发事件,添加或删除事件监听器,还能支持事件冒泡,阻止事件默认行为等等.在jquery的帮助下,使用这个方法 ...
- Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数、ColModel API、事件及方法
系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件 ...
- jQuery事件绑定方法bind、 live、delegate和on的区别
我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 1.准备知识 当我们在开始的时候,有些知识是必须具备的: 1 ...
- Javascript事件模型(三):JavaScript事件绑定方法总结(及Jquery)
JavaScript中绑定事件的方法主要有三种: 1 在DOM元素中直接绑定 2 JavaScript代码中直接绑定 3 绑定事件监听函数 JQuery中绑定事件的几种方法 主要有on().bind( ...
- 完美的jquery事件绑定方法on()
在讲on()方法之前,我们先讲讲在on()方法出现前的那些事件绑定方法: .live() jQuery 1.3新增的live()方法,使用方法例如以下: $("#info_table td& ...
- jQuery的4种事件绑定方法
jQuery中提供了四种绑定事件的方法,分别是bind.live.delegate.on,对应的解除监听的函数分别是unbind.die.undelegate.off: 一.on()方法(首选方法) ...
随机推荐
- [Noi2015]软件包管理器 题解
题目大意: 有n个软件安装包,除第一个以外,其他的要在另一个安装包的基础上安装,且无环,问在安装和卸载某个软件包时,这个操作实际上会改变多少个软件包的安装状态. 思路: 可构成树,用树链剖分,线段树. ...
- 20145308刘昊阳 《Java程序设计》实验一 Java开发环境的熟悉 实验报告
20145308刘昊阳 <Java程序设计>实验一报告 实验名称 Java开发环境的熟悉 实验内容 使用JDK编译.运行简单的Java程序 2.使用Eclipse 编辑.编译.运行.调试J ...
- 【BZOJ】1532: [POI2005]Kos-Dicing
题意 \(n\)个人\(m\)场比赛\((1 \le n \le 10000, 0 \le m \le 10000)\),给出每场比赛的两个选手,求赢得最多的人最少赢的场数. 分析 二分最多人赢的场数 ...
- 主席树+启发式合并(LT) BZOJ3123
好久没做题了,写道SBT又RE又T 查询:主席树裸题. 修改:对于两个树合并重建小的树. 注意fa[x][i]重新计算时要清空 #include<cstdio> #include<c ...
- python基础学习二——第二天
对于python而言,一切事物都是对象,对象是基于类创建的,对象继承了类的属性,方法等特性 一.int 首先我们来查看一下int包含了哪些函数 # python3.x dir(int) # ['__a ...
- push splice filter用法
checkedData.push(record); 直接在record 这个数组后面添加; var index =jQuery.inArray(record,checkedData);// 获取ind ...
- js判断微信浏览器
function is_weixin(){ //检查是否是微信浏览器 var ua = navigator.userAgent.toLowerCase(); if(ua.match(/MicroMes ...
- [LintCode] Wiggle Sort II 扭动排序之二
Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]... ...
- 手动创建oem
[oracle@std bin]$ /u02/app/product//db_1/bin/emca -config dbcontrol db -repos create STARTED EMCA at ...
- jQuery 插件autocomplete
jQuery 插件autocomplete 自动加载 参考: http://www.cnblogs.com/Peter-Zhang/archive/2011/10/22/2221147.html ht ...