原生Js与jquery的多组处理, 仅展开一个区块的折叠效果


Posted in Javascript onJanuary 09, 2011

需求是, 同一个页面, 有多组(不固定), 每组区块数量不一定一样的小区块. 要求每次只展开一个区块. 实现原理其实很简单, 点击导航, 若它的区块为隐藏, 则展开它, 同时, 隐藏掉同组其他区块; 若它的区块为展开, 则隐藏它, 同时, 展开同组其他区块中的一个. 一开始以为仅仅简单的两个遍历就能搞定. 但事实并非如此. 冷静思考了下, 通过点击的元素取到当前组的相关元素, 再单独处理当前组才合理. 顺着这个思路, 功能终于实现了, 写了原生Js版本, 用同样的思路写了个jQ版本. 时间关系, 写的也比较零散, 就没有封装. 其实, 对这种思路也不是很满意, 感觉太散了, 哪位大师有更好的思路请赐教.
原生Js与jquery的多组处理, 仅展开一个区块的折叠效果
jQ版区块的标题, 会有一个Js错误, 那是因为获取Js版下的h2时, 我偷了个懒, 把jQ的也遍历进去了. 我想, 实际应用中, 也不会有人同一个效果, 一边用Js一边用jQ吧. 核心代码点此查看样例

//原生Js版本 ***** start 
window.onload=function(){ 
//共用函数区 
var iBase={ 
//document.getElementById 
Id: function(name){return document.getElementById(name)}, 
//通过class获取元素 
GetByClass: function(name,tagName,elem){ 
var c=[]; 
var re=new RegExp('(^|\\s)'+name+'(|\\s$)'); 
var e=(elem || document).getElementsByTagName(tagName || '*'); 
for(var i=0; i < e.length; i++){ 
if(re.test(e[i].className)){ 
c.push(e[i]); 
} 
} 
return c; 
}, 
//获取样式属性 
AttrStyle: function(elem,attr){ 
if(elem.attr){ 
return elem.style[attr]; 
}else if(elem.currentStyle){ 
return elem.currentStyle[attr]; 
}else if(document.defaultView && document.defaultView.getComputedStyle){ 
attr=attr.replace(/([A-Z])/g,'-$1').toLowerCase(); 
return document.defaultView.getComputedStyle(elem,null).getPropertyValue(attr); 
}else{ 
return null; 
} 
}, 
//获取祖辈元素中符合指定样式的元素 
Parents: function(elem,name){ 
var r=new RegExp('(^|\\s)'+name+'(|\\s$)'); 
elem=elem.parentNode; 
if(elem!=null){ 
return r.test(elem.className) ? elem : iBase.Parent(elem,name) || null; 
} 
}, 
//取索引值 
Index: function(cur,obj){ 
for(var i=0; i < obj.length; i++){ 
if(obj[i]==cur){ 
return i; 
} 
} 
} } 
//变量定义 
var listBox=iBase.GetByClass('js','div'); 
var navItem=iBase.Id('demo').getElementsByTagName('h2');//此处将jQ区块中的h2也取到了,所以页面会有个小小的错误 
var icoItem=null,boxItem=null,boxDisplay=null,elemIndex=null,elemParent=null; 
//初始化展开第一个 
for(var i=0; i < listBox.length;i++){ 
iBase.GetByClass('box','div',listBox[i])[0].style.display='block'; 
listBox[i].getElementsByTagName('span')[0].innerHTML='-'; 
} 
//遍历所有点击项 
for(var i=0; i < navItem.length;i++){ 
navItem[i].onclick=function(){ 
elemParent=iBase.Parents(this,'js');//获取当前点击所在区块 
navItem=elemParent.getElementsByTagName('h2');//获取当前区块下的点击项 
icoItem=elemParent.getElementsByTagName('span');//获取当前区块下的展开关闭 
boxItem=iBase.GetByClass('box','div',elemParent);//获取需要控制的区块 
elemIndex=iBase.Index(this,navItem);//获取当前点击在当前区块点击项中的索引 
//切换展开关闭图标 
icoItem[elemIndex].innerHTML= icoItem[elemIndex].innerHTML=='-' ? '+' : '-'; 
if(iBase.AttrStyle(boxItem[elemIndex],'display')=='block'){ 
//控制项展开状态下,隐藏当前,展开其他的第一项 
//此处有个展开0/1的判断,因为当点击第一个时是不能再展开第一个的 
boxItem[elemIndex].style.display='none'; 
if(elemIndex==0){ 
boxItem[1].style.display='block'; 
icoItem[1].innerHTML='-' 
}else{ 
boxItem[0].style.display='block' 
icoItem[0].innerHTML='-' 
} 
}else{ 
//控制项展开状态下,展开当前,隐藏其他项 
boxItem[elemIndex].style.display='block'; 
for(var k=0;k < boxItem.length; k++){ 
if(k!=elemIndex){ 
boxItem[k].style.display='none'; 
icoItem[k].innerHTML='+'; 
} 
} 
} 
} 
} 
} 
//jQuery版本 ***** start 
$(function(){ 
//变量定义区 
var _listBox=$('.jq'); 
var _navItem=$('.jq>h2'); 
var _boxItem=null, _icoItem=null, _parents=null, _index=null; 
//初始化第一个展开 
_listBox.each(function(i){ 
$(this).find('div.box').eq(0).show(); 
$(this).find('h2>span').eq(0).text('-'); 
}); 
//遍历所有的点击项 
_navItem.each(function(i){ 
$(this).click(function(){ 
//找到当前点击父元素为listbox(单个区块)的元素 
_parents=$(this).parents('.listbox'); 
_navItem=_parents.find('h2');//此区块中的点击项 
_icoItem=_parents.find('span');//此区块中的展开关闭图标 
_boxItem=_parents.find('div.box');//此区块中展开关闭项 
_index=_navItem.index(this);//取得当前点击在当前区块下点击项中的索引值 
if(_boxItem.eq(_index).is(':visible')){ 
//若当前点击项下的展开关闭项是显示的,则关闭,同时展开另外项中的第一个 
_boxItem.eq(_index).hide().end().not(':eq('+_index+')').first().show(); 
_icoItem.eq(_index).text('+').end().not(':eq('+_index+')').first().text('-'); 
}else{ 
//若当前点击项下的展开关闭项是隐藏的,则展开,同时隐藏其他项 
_boxItem.eq(_index).show().end().not(':eq('+_index+')').hide(); 
_icoItem.eq(_index).text('-').end().not(':eq('+_index+')').text('+'); 
} 
}); 
}); 
});

演示地址:http://demo.3water.com/js/jsjq-flod-onlyone/index.htm
打包下载:https://3water.com/jiaoben/33950.html
本人来自Mr.Think的博客 http://mrthink.net/jsjq-flod-onlyone/
Javascript 相关文章推荐
JQuery与Ajax常用代码实现对比
Oct 03 Javascript
完美解决node.js中使用https请求报CERT_UNTRUSTED的问题
Jan 08 Javascript
bootstrap表单按回车会自动刷新页面的解决办法
Mar 08 Javascript
angular学习之从零搭建一个angular4.0项目
Jul 10 Javascript
解决vue移动端适配问题
Dec 12 Javascript
angular使用md5,CryptoJS des加密的方法
Jun 03 Javascript
新手如何快速理解js异步编程
Jun 24 Javascript
基于JS实现数字动态变化显示效果附源码
Jul 18 Javascript
使用 Vue 实现一个虚拟列表的方法
Aug 20 Javascript
vue如何在用户要关闭当前网页时弹出提示的实现
May 31 Javascript
Vue实现input宽度随文字长度自适应操作
Jul 29 Javascript
vue-simple-uploader上传成功之后的response获取代码
Sep 07 Javascript
JS中动态添加事件(绑定事件)的代码
Jan 09 #Javascript
jquery的extend和fn.extend的使用说明
Jan 09 #Javascript
js对象之JS入门之Array对象操作小结
Jan 09 #Javascript
理解JavaScript中的对象 推荐
Jan 09 #Javascript
最佳JS代码编写的14条技巧
Jan 09 #Javascript
JavaScript定义类或函数的几种方式小结
Jan 09 #Javascript
javascript中用星号表示预录入内容的实现代码
Jan 08 #Javascript
You might like
打造计数器DIY三步曲(上)
2006/10/09 PHP
php生成随机数或者字符串的代码
2008/09/05 PHP
Laravel如何使用数据库事务及捕获事务失败后的异常详解
2017/10/23 PHP
Laravel 集成微信用户登录和绑定的实现
2019/12/27 PHP
javascript 自定义事件初探
2009/08/21 Javascript
基于jquery打造的百分比动态色彩条插件
2012/09/19 Javascript
extjs关于treePanel+chekBox全部选中以及清空选中问题探讨
2013/04/02 Javascript
JavaScript简单实现鼠标拖动选择功能
2014/03/06 Javascript
Extjs 4.x 得到form CheckBox 复选框的值
2014/05/04 Javascript
javascript学习笔记--数字格式类型
2014/05/22 Javascript
如何编写高质量JS代码
2014/12/28 Javascript
14款经典网页图片和文字特效的jQuery插件-前端开发必备
2015/08/25 Javascript
vue自定义全局组件(自定义插件)的用法
2018/01/30 Javascript
使用ECharts实现状态区间图
2018/10/25 Javascript
webpack中如何使用雪碧图的示例代码
2018/11/11 Javascript
Layui选项卡制作历史浏览记录的方法
2019/09/28 Javascript
[01:28]国服启动器接入蒸汽平台操作流程视频
2021/03/11 DOTA
为python设置socket代理的方法
2015/01/14 Python
python定时检查某个进程是否已经关闭的方法
2015/05/20 Python
解读! Python在人工智能中的作用
2017/11/14 Python
python中的json总结
2018/10/11 Python
Python sep参数使用方法详解
2020/02/12 Python
tensorflow中tf.reduce_mean函数的使用
2020/04/19 Python
Python使用urlretrieve实现直接远程下载图片的示例代码
2020/08/17 Python
CSS3实现红包抖动效果
2020/12/23 HTML / CSS
几个数据库方面的面试题
2016/07/01 面试题
请用Java实现列出某个目录下的所有文件
2013/09/23 面试题
思想品德课教学反思
2014/02/10 职场文书
《难忘的泼水节》教学反思
2014/02/27 职场文书
党代会心得体会
2014/09/04 职场文书
写景作文评语集锦
2014/12/25 职场文书
个人年终总结结尾
2015/03/06 职场文书
个人求职意向书
2015/05/11 职场文书
车辆安全隐患排查制度
2015/08/05 职场文书
mysql事务对效率的影响分析总结
2021/10/24 MySQL
使用vue判断当前环境是安卓还是IOS
2022/04/12 Vue.js