原生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 八进制转义字符(8进制)
Apr 08 Javascript
javascript学习笔记(十五) js间歇调用和超时调用
Jun 20 Javascript
JavaScript实现点击按钮切换网页背景色的方法
Oct 17 Javascript
jQuery unbind()方法实例详解
Jan 19 Javascript
老生常谈onBlur事件与onfocus事件(js)
Jul 09 Javascript
js获取form表单所有数据的简单方法
Aug 18 Javascript
关于Javascript回调函数的一个妙用
Aug 29 Javascript
angularJS利用ng-repeat遍历二维数组的实例代码
Jun 03 Javascript
基于Vuejs和Element的注册插件的编写方法
Jul 03 Javascript
如何去除vue项目中的#及其ie9兼容性
Jan 11 Javascript
基于openlayers4实现点的扩散效果
Aug 17 Javascript
node.js微信小程序配置消息推送的实现
Feb 13 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中把错误日志保存在系统日志中(Windows系统)
2015/06/23 PHP
Smarty保留变量用法分析
2016/05/23 PHP
Ubuntu上安装yaf扩展的方法
2018/01/29 PHP
PHP基于面向对象封装的分页类示例
2019/03/15 PHP
详解Laravel服务容器的绑定与解析
2019/11/05 PHP
javascript 动态参数判空操作
2008/12/22 Javascript
js 覆盖和重载 函数
2009/09/25 Javascript
拖动布局之保存布局页面cookies篇
2010/10/29 Javascript
js中top/parent/frame概述及案例应用
2013/02/06 Javascript
绑定回车enter事件代码
2014/05/18 Javascript
配置Grunt的Task时通配符支持和动态生成文件名问题
2015/09/06 Javascript
浅析Javascript中bind()方法的使用与实现
2016/04/29 Javascript
jQuery html表格排序插件tablesorter使用方法详解
2017/02/10 Javascript
JS解析url查询参数的简单代码
2017/08/06 Javascript
axios发送post请求,提交图片类型表单数据方法
2018/03/16 Javascript
JS 使用 window对象的print方法实现分页打印功能
2018/05/16 Javascript
JS使用tween.js动画库实现轮播图并且有切换功能
2018/07/17 Javascript
element-ui 设置菜单栏展开的方法
2018/08/22 Javascript
Angularjs Ng_repeat中实现复选框选中并显示不同的样式方法
2018/09/12 Javascript
vue prop属性传值与传引用示例
2019/11/13 Javascript
js实现上传图片并显示图片名称
2019/12/18 Javascript
javascript实现计算器功能
2020/03/30 Javascript
Python实现删除文件但保留指定文件
2015/06/21 Python
python pandas 如何替换某列的一个值
2018/06/09 Python
python 删除字符串中连续多个空格并保留一个的方法
2018/12/22 Python
Python 调用 zabbix api的方法示例
2019/01/06 Python
详解用python实现基本的学生管理系统(文件存储版)(python3)
2019/04/25 Python
如何快速一次性卸载所有python包(第三方库)呢
2020/10/20 Python
最新pycharm安装教程
2020/11/18 Python
基于python实现监听Rabbitmq系统日志代码示例
2020/11/28 Python
css3学习心得分享
2013/08/19 HTML / CSS
求职信的七个关键技巧
2014/02/05 职场文书
现场施工员岗位职责
2014/03/10 职场文书
党员剖析材料范文
2014/09/30 职场文书
公务员政审个人总结
2015/02/12 职场文书
离婚答辩状范文
2015/05/22 职场文书