原生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 在firebug调试时用console.log的方法
May 10 Javascript
Javascript级联下拉菜单以及AJAX数据验证核心代码
May 10 Javascript
自写的jQuery异步加载数据添加事件
May 15 Javascript
深入理解javascript变量声明
Nov 20 Javascript
jQuery菜单插件用法实例
Jul 25 Javascript
JS给Textarea文本框添加行号的方法
Aug 20 Javascript
jQuery实现的个性化返回底部与返回顶部特效代码
Oct 30 Javascript
浅谈jquery上下滑动的注意事项
Oct 13 Javascript
vue实现城市列表选择功能
Jul 16 Javascript
微信小程序文字显示换行问题
Jul 28 Javascript
js实现点击生成随机div
Jan 16 Javascript
Vue项目vscode 安装eslint插件的方法(代码自动修复)
Apr 15 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对象克隆clone用法示例
2016/09/28 PHP
jquery的Theme和Theme Switcher使用小结
2010/09/08 Javascript
关于js new Date() 出现NaN 的分析
2012/10/23 Javascript
js(JavaScript)实现TAB标签切换效果的简单实例
2014/02/26 Javascript
javascript动态生成树形菜单的方法
2015/11/14 Javascript
jQuery版本升级踩坑大全
2016/01/12 Javascript
easyui datagrid 大数据加载效率慢,优化解决方法(推荐)
2016/11/09 Javascript
AngularJS控制器controller给模型数据赋初始值的方法
2017/01/04 Javascript
通过npm引用的vue组件使用详解
2017/03/02 Javascript
详解angular2实现ng2-router 路由和嵌套路由
2017/03/24 Javascript
详解vue项目构建与实战
2017/06/27 Javascript
记一次Vue.js混入mixin的使用(分权限管理页面)
2019/04/17 Javascript
实现一个 Vue 吸顶锚点组件方法
2019/07/10 Javascript
详解Vue的watch中的immediate与watch是什么意思
2019/12/30 Javascript
ES6中Promise的使用方法实例总结
2020/02/18 Javascript
python中stdout输出不缓存的设置方法
2014/05/29 Python
Python基于正则表达式实现文件内容替换的方法
2017/08/30 Python
对python sklearn one-hot编码详解
2018/07/10 Python
python根据txt文本批量创建文件夹
2020/12/08 Python
Python Django 封装分页成通用的模块详解
2019/08/21 Python
用python批量移动文件
2021/01/14 Python
英国拳击装备购物网站:RDX Sports
2018/01/23 全球购物
美国相机和电子产品零售商:Beach Camera
2020/11/26 全球购物
在c#中using和new这两个关键字有什么意义
2013/05/19 面试题
程序员经常用到的UNIX命令
2015/04/13 面试题
信息技术专业大学生个人的自我评价
2013/10/05 职场文书
软件工程专业推荐信
2013/10/28 职场文书
清洁工表扬信
2014/01/08 职场文书
优秀的导游求职信范文
2014/04/06 职场文书
工作失误检讨书(3篇)
2014/10/11 职场文书
资产运营委托书范本
2014/10/16 职场文书
2014年高中班主任工作总结
2014/11/08 职场文书
质量负责人岗位职责
2015/02/15 职场文书
校长一岗双责责任书
2015/05/09 职场文书
2015年秋学期教研工作总结
2015/10/14 职场文书
英语版自我评价,35句话轻松搞定
2019/10/08 职场文书