jQuery链式调用与show知识浅析
2016-05-11 00:00
761 查看
上篇文章给大家介绍了jQuery的框架,有关jquery的基础知识可以参考下。
jQuery使用许久了,但是有一些API的实现实在想不通。下面将使用简化的代码来介绍,主要关注jQuery的实现思想。
相较于上一篇,代码更新了:21~78
先拿hide函数热身一下。如上篇提到的,jQuery会将获取到的nodeList处理成数组,所以一上来,我们用forEach处理数组里的每一个node节点。
接下来,我们只需要将每一个节点的style.display置为'none'即可隐藏。很简单,对吧?(⊙0⊙) 。oldDisplay和return this先不管╰( ̄▽ ̄)╮
其中isHidden是判断该元素是否隐藏:已经隐藏的元素就没必要再去处理了,直接跳过
--------------------------
接下来,来个稍繁琐的show。先抛出一个问题来引发一系列问题:
hide某个元素只需要将display:none,那么show呢?
display:block不就行了吗?这样确实可以将元素显示出来。但是万一元素原来的值是display:inline呢?
那在hide处保存原来的值不就行了吗?就像以下的代码:
要是执行show前没有不执行hide呢?比如下面这种情况,不就没有oldDisplay了吗(⊙0⊙)
好,关键的地方到了:我们获取元素display的默认值就可以了吧?比如div默认是block,span默认是inline。
思路有了,那么接下来的问题是:如何获取元素display的默认值?
嘿嘿嘿,想不到吧?这里需要用点小技巧,大体思路如下:通过nodeName创建一个新的标签,再获取。
有个地方可以再优化一下,getDisplay获取到元素display默认值后,可以使用jQuery的cache机制存起来(实际上jQuery也是这么做了)。
然后,综合这两种情况:
以为这样就结束了?NO,show函数的情况还是挺复杂的,我们大致要应对这几种情况:
最终,show函数变成了这鬼样ψ(╰_╯)。大致思路如下:
--------------------------
链式调用就是类似这种情况:
实现起来非常简单,只要在每个函数后面return this即可
--------------------------
有同学说:喂!这个show,hide不对吧?是不是漏了时间参数? 用setTimeOut自己实现吧~>_<~+。
本节最主要是让大家知道jQuery需要考虑的情况非常多(很多脏活)。即时简化了代码,依然还是这么长。
写完后,发现show还有一种情况没考虑:
Javascript 链式调用实现代码(参考jquery)
JavaScript对象链式操作代码(jquery)
jQuery的链式调用浅析
浅析jQuery的链式调用之each函数
jQuery链式操作如何实现以及为什么要用链式操作
jquery链式操作的正确使用方法
使用JavaScript链式编程实现模拟Jquery函数
jQuery链式操作实例分析
jQuery对象的链式操作用法分析
jQuery使用许久了,但是有一些API的实现实在想不通。下面将使用简化的代码来介绍,主要关注jQuery的实现思想。
相较于上一篇,代码更新了:21~78
(function(window, undefined){ function jQuery(sel){ return new jQuery.prototype.init(sel); } jQuery.prototype = { constructor: jQuery, init: function(sel){ if(typeof sel === 'string'){ var that = this; var nodeList = document.querySelectorAll(sel); Array.prototype.forEach.call(nodeList, function(val, i){ that[i] = val; }) this.selector = sel; this.length = nodeList.length; } }, show: function(){ Array.prototype.forEach.call(this, function(node){ //if(node.style) continue; //textnode没有style //删除style上的display:none var display = node.style.display; if(display === 'none'){ //dispaly置为空后,css如果有display则css的生效 //否则默认的生效 node.style.display = ''; } //元素display值为非默认值情况,需要还原为oldDisplay:div->display:inline-block //或 检测css上的display是否为none if(node.style.display==='' || isHidden(node)){ //有oldDispaly则设置 if(node.oldDisplay) node.style.display = node.oldDisplay; //没有则设置为元素默认值或元素当前值 else node.style.display = getDisplay(node); } }) //链式调用 return this; }, hide: function(){ Array.prototype.forEach.call(this, function(node){ if(!isHidden(node)) { //jQuery使用其cache机制存储信息,这里简化一下 //直接挂载在对应的dom下 node.oldDisplay = getDisplay(node); node.style.display = 'none'; } }) return this; } } function getDisplay(node){ var display = window.getComputedStyle(node, null).getPropertyValue('display'); if(display === 'none'){ var dom = document.createElement(node.nodeName); //插入到body中 document.body.appendChild(dom); //即可获取到元素display的默认值 var display = window.getComputedStyle(dom, null).getPropertyValue('display'); document.body.removeChild(dom); } return display; } function isHidden(node) { //忽略未append进document的元素这种隐藏情况:$('<div>block</div>')未append return window.getComputedStyle(node, null).getPropertyValue('display') === 'none'; } jQuery.prototype.init.prototype = jQuery.prototype; window.$ = jQuery; })(window);
先拿hide函数热身一下。如上篇提到的,jQuery会将获取到的nodeList处理成数组,所以一上来,我们用forEach处理数组里的每一个node节点。
接下来,我们只需要将每一个节点的style.display置为'none'即可隐藏。很简单,对吧?(⊙0⊙) 。oldDisplay和return this先不管╰( ̄▽ ̄)╮
hide: function(){ Array.prototype.forEach.call(this, function(node){ if(!isHidden(node)) { //jQuery使用其cache机制存储信息,这里简化一下 //直接挂载在对应的dom下 node.oldDisplay = getDisplay(node); node.style.display = 'none'; } }) return this; }
其中isHidden是判断该元素是否隐藏:已经隐藏的元素就没必要再去处理了,直接跳过
function isHidden(node) { //忽略未append进document的元素这种隐藏情况:$('<div>block</div>')未append return window.getComputedStyle(node, null).getPropertyValue('display') === 'none'; }
--------------------------
接下来,来个稍繁琐的show。先抛出一个问题来引发一系列问题:
hide某个元素只需要将display:none,那么show呢?
display:block不就行了吗?这样确实可以将元素显示出来。但是万一元素原来的值是display:inline呢?
那在hide处保存原来的值不就行了吗?就像以下的代码:
node.oldDisplay = getDisplay(node);
要是执行show前没有不执行hide呢?比如下面这种情况,不就没有oldDisplay了吗(⊙0⊙)
<style> div{ display:none; } </style> <div>display:none</div>$('div').show()
好,关键的地方到了:我们获取元素display的默认值就可以了吧?比如div默认是block,span默认是inline。
思路有了,那么接下来的问题是:如何获取元素display的默认值?
嘿嘿嘿,想不到吧?这里需要用点小技巧,大体思路如下:通过nodeName创建一个新的标签,再获取。
有个地方可以再优化一下,getDisplay获取到元素display默认值后,可以使用jQuery的cache机制存起来(实际上jQuery也是这么做了)。
function getDisplay(node){ var display = window.getComputedStyle(node, null).getPropertyValue('display'); if(display === 'none'){ var dom = document.createElement(node.nodeName); //插入到body中 document.body.appendChild(dom); //即可获取到元素display的默认值 var display = window.getComputedStyle(dom, null).getPropertyValue('display'); document.body.removeChild(dom); } return display; }
然后,综合这两种情况:
//有oldDispaly则设置 if(node.oldDisplay) node.style.display = node.oldDisplay; //没有则设置为元素默认值或元素当前值 else node.style.display = getDisplay(node);
以为这样就结束了?NO,show函数的情况还是挺复杂的,我们大致要应对这几种情况:
<style> #none,#none2{ display: none; } </style> <body> <div id="div">默认值为block</div> <span id="span">默认值为inline</span> <div id="div2" style="display:inline-block;">修改为inline-block</div> <div id="none">通过css隐藏了</div> <div id="none2" style="display:none">通过css和style隐藏了</div> </body>
最终,show函数变成了这鬼样ψ(╰_╯)。大致思路如下:
show: function(){ Array.prototype.forEach.call(this, function(node){ //if(node.style) continue; //textnode没有style //删除style上的display:none var display = node.style.display; if(display === 'none'){ //dispaly置为空后,css如果有display则css的生效 //否则默认的生效 node.style.display = ''; } //元素display值为非默认值情况,需要还原为oldDisplay:div->display:inline-block //或 检测css上的display是否为none if(node.style.display==='' || isHidden(node)){ //有oldDispaly则设置 if(node.oldDisplay) node.style.display = node.oldDisplay; //没有则设置为元素默认值或当前值 else node.style.display = getDisplay(node); } }) }
--------------------------
链式调用就是类似这种情况:
$('div').show().hide().css('height','300px').toggle()
实现起来非常简单,只要在每个函数后面return this即可
--------------------------
有同学说:喂!这个show,hide不对吧?是不是漏了时间参数? 用setTimeOut自己实现吧~>_<~+。
本节最主要是让大家知道jQuery需要考虑的情况非常多(很多脏活)。即时简化了代码,依然还是这么长。
写完后,发现show还有一种情况没考虑:
div{ display:none !important; } <div>大家自己开脑洞,怎么处理吧(⊙0⊙)</div>
您可能感兴趣的文章:
模仿jQuery each函数的链式调用Javascript 链式调用实现代码(参考jquery)
JavaScript对象链式操作代码(jquery)
jQuery的链式调用浅析
浅析jQuery的链式调用之each函数
jQuery链式操作如何实现以及为什么要用链式操作
jquery链式操作的正确使用方法
使用JavaScript链式编程实现模拟Jquery函数
jQuery链式操作实例分析
jQuery对象的链式操作用法分析
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- JavaScript演示排序算法
- 2015-2016网页设计趋势分析 Web Design of Trends
- jQuery Ajax 跨域调用
- 移动端的长按事件
- jquery教程靠边站,一分钱不花让你免费学会jquery
- JQuery+Strusts1.x无刷新登录
- $.ajax()方法详解
- jQuery ajax - ajax() 方法
- JavaScript 各种遍历方式详解
- 数组方法汇总
- jQuery Html控件基本操作(日常收集整理)
- jQuery插件实现文字无缝向上滚动效果代码
- jQuery菜单插件用法实例
- JQuery 初体验(建议学习jquery)
- 基于Jquery和CSS3制作数字时钟附源码下载(CSS3篇)
- Jquery实现的table最后一行添加样式的代码
- jQuery实现向下滑出的平滑下拉菜单效果
- jQuery 练习[一] 学习jquery的准备工作