原生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 相关文章推荐
网页里控制图片大小的相关代码
Jun 13 Javascript
js prototype 格式化数字 By shawl.qiu
Apr 02 Javascript
优化javascript的执行效率一些方法总结
Dec 25 Javascript
JavaScript中的ArrayBuffer详细介绍
Dec 08 Javascript
垃圾回收器的相关知识点总结
May 13 Javascript
jQuery获取随机颜色的实例代码
May 21 jQuery
vue路由跳转传参数的方法
May 06 Javascript
小程序识别身份证,银行卡,营业执照,驾照的实现
Nov 05 Javascript
详解vue-router 动态路由下子页面多页共活的解决方案
Dec 22 Javascript
ckeditor一键排版功能实现方法分析
Feb 06 Javascript
JavaScript实现打砖块游戏
Feb 25 Javascript
详解TypeScript中的类型保护
Apr 29 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
PHP实现MVC开发得最简单的方法――模型
2007/04/10 PHP
PHP求小于1000的所有水仙花数的代码
2012/01/10 PHP
解析PHP计算页面执行时间的实现代码
2013/06/18 PHP
迪菲-赫尔曼密钥交换(Diffie?Hellman)算法原理和PHP实现版
2015/05/12 PHP
详解php中空字符串和0之间的关系
2016/10/23 PHP
js onkeypress与onkeydown 事件区别详细说明
2012/12/13 Javascript
JavaScript起点(严格模式深度了解)
2013/01/28 Javascript
jquery ajax提交整个表单元素的快捷办法
2013/03/27 Javascript
网页实时显示服务器时间和javscript自运行时钟
2014/06/09 Javascript
Extjs Label的 fieldLabel和html属性值对齐的方法
2014/06/15 Javascript
node爬取微博的数据的简单封装库nodeweibo使用指南
2015/01/02 Javascript
JavaScript File分段上传
2016/03/10 Javascript
JS闭包用法实例分析
2017/03/27 Javascript
vue2.x 父组件监听子组件事件并传回信息的方法
2017/07/17 Javascript
原生JS实现网页手机音乐播放器 歌词同步播放的示例
2018/02/02 Javascript
vue项目中在外部js文件中直接调用vue实例的方法比如说this
2019/04/28 Javascript
JavaScript如何处理移动端拍摄图片旋转问题
2019/11/16 Javascript
js实现复制粘贴的两种方法
2020/12/04 Javascript
原生JS实现音乐播放器
2021/01/26 Javascript
[02:42]2014DOTA2国际邀请赛 三冰专访:我会打到Ti20
2014/07/13 DOTA
Python中将字典转换为XML以及相关的命名空间解析
2015/10/15 Python
Python3爬虫关于识别检验滑动验证码的实例
2020/07/30 Python
python3.5的包存放的具体路径
2020/08/16 Python
CSS3模拟IOS滑动开关效果
2016/09/28 HTML / CSS
Tarte Cosmetics官网:美国最受欢迎的化妆品公司之一
2017/08/24 全球购物
DERMAdoctor官网:美国著名皮肤护理品牌
2019/07/06 全球购物
营业经理岗位职责
2013/11/10 职场文书
影视艺术学院毕业生自荐信
2013/11/13 职场文书
《春天来了》教学反思
2014/04/07 职场文书
演讲稿祖国在我心中
2014/05/04 职场文书
2014年档案管理员工作总结
2014/12/01 职场文书
本科毕业答辩开场白
2015/05/27 职场文书
简历自我评价范文
2019/04/24 职场文书
低端且暴利的线上线下创业项目分享
2019/09/03 职场文书
pandas中DataFrame重置索引的几种方法
2021/05/24 Python
Python初识逻辑与if语句及用法大全
2021/08/07 Python