原生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 相关文章推荐
JavaScript中的私有成员
Sep 18 Javascript
[原创]后缀就扩展名为js的文件是什么文件
Dec 06 Javascript
Jquery倒数计时按钮setTimeout的实例代码
Jul 04 Javascript
css样式标签和js语法属性区别
Nov 06 Javascript
网页下载文件期间如何防止用户对网页进行其他操作
Jun 27 Javascript
jQuery中get()方法用法实例
Dec 27 Javascript
JavaScript将Web页面内容导出到Word及Excel的方法
Feb 13 Javascript
jQuery实现文本框邮箱输入自动补全效果
Nov 17 Javascript
AngularJS指令中的绑定策略实例分析
Dec 14 Javascript
AngularJS中下拉框的高级用法示例
Oct 11 Javascript
vue+element项目中过滤输入框特殊字符小结
Aug 07 Javascript
vue自定义标签和单页面多路由的实现代码
May 03 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启用zlib压缩文件的配置方法
2013/06/12 PHP
关于PHP二进制流 逐bit的低位在前算法(详解)
2013/06/13 PHP
JSON 和 JavaScript eval使用说明
2010/06/13 Javascript
js动态修改整个页面样式达到换肤效果
2014/05/23 Javascript
网页中表单按回车就自动提交的问题的解决方案
2014/11/03 Javascript
js时间日期格式化封装函数
2014/12/02 Javascript
Javascript实现Web颜色值转换
2015/02/05 Javascript
全面解析Bootstrap弹窗的实现方法
2015/12/01 Javascript
jQuery数据检索中根据关键字快速定位GridView指定行的实现方法
2016/06/08 Javascript
Angular.js实现多个checkbox只能选择一个的方法示例
2017/02/24 Javascript
利用JavaScript在网页实现八数码启发式A*算法动画效果
2017/04/16 Javascript
jQuery动态添加li标签并添加属性和绑定事件方法
2018/02/24 jQuery
js中DOM事件绑定分析
2018/03/18 Javascript
微信小程序五子棋游戏AI实现方法【附demo源码下载】
2019/02/20 Javascript
js实现鼠标拖拽缩放div实例代码
2019/03/25 Javascript
深入学习JavaScript中的bom
2019/05/27 Javascript
ES6小技巧之代替lodash
2019/06/07 Javascript
vuejs中父子组件之间通信方法实例详解
2020/01/17 Javascript
使用Nginx+uWsgi实现Python的Django框架站点动静分离
2016/03/21 Python
使用Python的Flask框架构建大型Web应用程序的结构示例
2016/06/04 Python
利用Python中unittest实现简单的单元测试实例详解
2017/01/09 Python
python安装模块如何通过setup.py安装(超简单)
2018/05/05 Python
解决python opencv无法显示图片的问题
2018/10/28 Python
Python Django基础二之URL路由系统
2019/07/18 Python
python selenium实现发送带附件的邮件代码实例
2019/12/10 Python
Python使用Selenium模拟浏览器自动操作功能
2020/09/08 Python
Carter’s OshKosh加拿大:购买婴幼儿服装和童装
2018/11/27 全球购物
美国用餐电影院:Alamo Drafthouse Cinema
2020/01/23 全球购物
小米官方旗舰店:Xiaomi
2020/08/07 全球购物
函授毕业生自我鉴定
2013/11/06 职场文书
新入职员工的自我介绍演讲稿
2014/01/02 职场文书
2014年应届大学生毕业自我鉴定
2014/01/31 职场文书
社区精神文明建设汇报材料
2014/08/17 职场文书
党员教师批评与自我批评发言稿
2014/10/15 职场文书
2015年党风建设工作总结
2015/04/29 职场文书
python 解决微分方程的操作(数值解法)
2021/05/26 Python