原生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仿小米手机抢购页面倒计时效果
Dec 16 Javascript
谈谈我对JavaScript DOM事件的理解
Dec 18 Javascript
BootStrap响应式导航条实例介绍
May 06 Javascript
jQuery EasyUI datagrid在翻页以后仍能记录被选中行的实现代码
Aug 15 Javascript
微信小程序 保留小数(toFixed)详细介绍
Nov 16 Javascript
JS键盘版计算器的制作方法
Dec 03 Javascript
BootstrapTable请求数据时设置超时(timeout)的方法
Jan 22 Javascript
浅谈jQuery的bind和unbind事件(绑定和解绑事件)
Mar 02 Javascript
微信小程序自定义toast实现方法详解【附demo源码下载】
Nov 28 Javascript
Vue项目安装插件并保存
Jan 28 Javascript
JavaScript判断浏览器运行环境的详细方法
Jun 30 Javascript
解决vue v-for src 图片路径问题 404
Nov 12 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
德生1994机评
2021/03/02 无线电
php在多维数组中根据键名快速查询其父键以及父键值的代码
2011/05/07 PHP
ThinkPHP框架使用redirect实现页面重定向的方法实例分析
2018/04/12 PHP
10个基于jQuery或JavaScript的WYSIWYG 编辑器整理
2010/05/06 Javascript
获取css样式表内样式的js函数currentStyle(IE),defaultView(FF)
2011/02/14 Javascript
jquery动态增加text元素以及删除文本内容实例代码
2013/07/01 Javascript
JavaScript中的常见问题解决方法(乱码,IE缓存,代理)
2013/11/28 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
详解JS中Array对象扩展与String对象扩展
2016/01/07 Javascript
javascript函数自动执行常用方法汇总
2016/03/28 Javascript
JavaScript类的写法
2016/09/17 Javascript
javascript阻止事件冒泡和浏览器的默认行为
2017/01/21 Javascript
Angularjs 事件指令详细整理
2017/07/27 Javascript
JavaScript callback回调函数用法实例分析
2018/05/08 Javascript
vue 实现v-for循环回来的数据动态绑定id
2019/11/07 Javascript
vue中keep-alive,include的缓存问题
2019/11/26 Javascript
[56:35]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第一局
2016/03/06 DOTA
详解Python字符串对象的实现
2015/12/24 Python
分享python数据统计的一些小技巧
2016/07/21 Python
matplotlib绘图实例演示标记路径
2018/01/23 Python
python复制列表时[:]和[::]之间有什么区别
2018/10/16 Python
python3.7 openpyxl 删除指定一列或者一行的代码
2019/10/08 Python
Python实现图片识别加翻译功能
2019/12/26 Python
tensorflow使用range_input_producer多线程读取数据实例
2020/01/20 Python
tensorflow实现读取模型中保存的值 tf.train.NewCheckpointReader
2020/02/10 Python
HTML5的结构和语义(4):语义性的内联元素
2008/10/17 HTML / CSS
Armor Lux法国官方网站:水手服装、成衣和内衣
2020/05/26 全球购物
儿媳婚宴答谢词
2014/01/14 职场文书
公司担保书范文
2014/05/21 职场文书
机械专业应届毕业生自荐书
2014/06/12 职场文书
教师节学生演讲稿
2014/09/03 职场文书
2014年电教工作总结
2014/12/19 职场文书
婚礼女方父母答谢词
2015/01/04 职场文书
2015毕业生简历自我评价
2015/03/02 职场文书
任命书格式范文
2015/09/22 职场文书
Golang的继承模拟实例
2021/06/30 Golang