注:该练习中涉及的move方法(移动效果)可参考博文“JavaScript_网页中使用按钮控制图形的移动效果(/md/?articleId=115607200)”
若对此练习有所疑惑可参考尚硅谷李立超老师在B站的js基础教程(/video/BV1YW411T7GX?p=138)
下面我们看一下该下拉菜单的效果图:
以下为源码和解析:
css文件:second.css
@charset "utf-8";/* sdmenu */div.sdmenu {width: 150px;margin: 100px auto;font-family: Arial, sans-serif;font-size: 12px;padding-bottom: 10px;background: url(bottom.gif) no-repeat right bottom;color: #fff;}div.sdmenu div {background: url(title.gif) repeat-x;overflow: hidden;}div.sdmenu div:first-child{background: url(toptitle.gif) no-repeat;}div.sdmenu div.collapsed{height: 25px;}div.sdmenu div span{display: block;height: 15px;overflow: hidden;padding: 5px 25px;font-weight: bold;color: white;background: url(expanded.gif) no-repeat 10px center;cursor: pointer;border-bottom: 1px solid #ddd;}div.sdmenu div.collapsed span{background-image: url(collapsed.gif);}div.sdmenu div a{padding: 5px 10px;background: #eee;display: block;border-bottom: 1px solid #ddd;color: #066;}div.sdmenu div a.current{background: #ccc;}div.sdmenu div a:hover{background: #066 url(linkarrow.gif) no-repeat right center;color: #fff;text-decoration: none;}
html及JS源码:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>二级菜单</title><link rel="stylesheet" href="css/second.css"><style>*{padding: 0px;margin: 0px;list-style-type: none;}a,img{border: 0px;text-decoration: none;}body{font: 12px/180%;}</style><script src="./js/tools.js"></script><script>window.onload = function(){/* 我们的每一个菜单都是一个div当div具有collapsed这个类时,div就是折叠状态当div没有这个类时,div就是展开状态点击菜单,切换菜单的显示状态*///获取所有的class为menuSpan的元素var menuSpan = document.querySelectorAll(".menuSpan");console.log(menuSpan.length); //定义一个变量,保存当前打开的菜单var openDiv = menuSpan[0].parentNode;//绑定span单击响应函数for(var i=0; i<menuSpan.length; i++){menuSpan[i].onclick = function(){//this代表当前点击的span//获取当前span的父元素var parentDiv = this.parentNode;toggleMenu(parentDiv);//判断openDiv和parentDiv是否相同if(openDiv != parentDiv && !hasClass(openDiv, "collapsed")){//打开菜单以后,应该关闭之前打开的菜单//为了可以统一处理动画过渡效果,我们希望将addClass改为toggleClass;// addClass(openDiv, "collapsed");// 此处toggleClass()不需要有移除功能// toggleClass(openDiv, "collapsed");//切换菜单的显示状态toggleMenu(openDiv);}//修改openDiv 为当前打开的菜单openDiv = parentDiv;};}//切换菜单的折叠和显示状态function toggleMenu(obj){var begin = obj.offsetHeight;//切换parentDiv的显示toggleClass(obj, "collapsed");//在切换类之后,获取一个高度var end = obj.offsetHeight;// console.log(begin+ " "+end);// 动画效果就是将高度从begin向end过渡// 将元素的高度重置为beginobj.style.height = begin + "px"// console.log(parentDiv.style.height);// 执行动画,从begin向end过渡move(obj, "height", end, 10, function(){// 动画执行完毕,内联样式已经没有存在的意义,需删除obj.style.height = "";});}};</script></head><body><div id="my_menu" class="sdmenu"><div><span class="menuSpan">在线工具</span><a href="#">图像优化</a><a href="#">收藏夹图标生成器</a><a href="#">邮件</a><a href="#">htaccess密码</a><a href="#">梯度图像</a><a href="#">按钮生成器</a></div><div class="collapsed"><span class="menuSpan">支持我们</span><a href="#">推荐我们</a><a href="#">链接我们</a><a href="#">网络资源</a></div><div class="collapsed"><span class="menuSpan">合作伙伴</span><a href="#">JavaScript工具包</a><a href="#">CSS驱动</a><a href="#">CodingForums</a><a href="#">CSS例子</a></div><div class="collapsed"><span class="menuSpan">测试电流</span><a href="#">Current or not</a><a href="#">Current or not</a><a href="#">Current or not</a><a href="#">Current or not</a></div></div></body></html>
通用的js方法:tool.js
注:该文件中主要包含三方面的方法,即:获取元素属性方法、移动动画方法、增删元素类方法
源码:
//移动效果————move()方法/* 目前我们的定时器的标识由全局变量timer保存所有的执行正在执行的定时器都在这个变量中保存*/var timer;//创建一个可以执行简单动画的函数/* 参数:obj:要执行动画的对象st: 要执行动画的样式,比如:left、top、widthtarget: 执行动画的目标位置speed: 移动的速度(正数向右移动,负数向左移动)callback: 回调函数,这个函数将会在动画执行完毕以后执行*/function move(obj, st, target, speed, callback){clearInterval(obj.timer);var current = parseInt(getStyle(obj, st));//判断速度的正负值//如果从0向400移动,则speed为正//如果从400向0移动,则speed为负console.log(current + " " + target);if(current > target){speed = -speed;}obj.timer = setInterval(function(){//获取box1的原来的left值var oldValue = parseInt(getStyle(obj, st));console.log(oldValue);//在旧值的基础上增加var newValue = oldValue + speed ;//将新值设置给box1obj.style[st] = newValue + "px"; if(speed < 0 && newValue <= target){obj.style[st] = target + "px"; clearInterval(obj.timer);//动画执行完毕,调用回调函数callback && callback(); //如果有callback则执行,否则不执行}else if(speed > 0 && newValue >= target){obj.style[st] = target + "px";clearInterval(obj.timer);//动画执行完毕,调用回调函数callback && callback(); //如果有callback则执行,否则不执行}}, 10);}//版本适配后的获取元素属性的方法_getStyle()function getStyle(obj, name){//此处条件不可直接使用getComputedStyle作为参数,因为在浏览器中变量没找到会报错// 而作为window的属性使用,属性找不到会返回false,如果是IE8浏览器则会返回false// 如果是IE8以上的版本或者其他类型浏览器,则返回trueif(window.getComputedStyle){//正常浏览器的方式,具有getComputedStyle方法return getComputedStyle(obj, null)[name];}else{//IE8的方式,没有getComputedStyle方法return obj.currentStyle[name];}//另一种方法//该方法有缺陷,因为IE9/10/11即含有currentStyle属性有含有getComputedStyle方法// if(obj.currentStyle){//return obj.currentStyle[name];// }else{//return obj.getComputedStyle[name];// }} //删除、添加、替换、判断类是否存在 的方法(removeClass、addClass、toggleClass、hasClass)//定义一个函数,用来向一个元素中添加指定的class属性值/* 参数:obj 要添加class属性的元素ch 要添加的class值*/function addClass(obj, cn){console.log(hasClass(obj, cn));if(!hasClass(obj, cn)){obj.className += " " + cn; // 空格不可缺}}/* 判断一个元素中是否含有指定的class属性值*/function hasClass(obj, cn){//判断obj是否含有cn// if( obj.className.indexOf(" " + cn + " ") > -1){//console.log(obj.className.indexOf(cn));//return true;// }else{//return false;// }//创建一个正则表达式var reg = new RegExp("\\b" + cn + "\\b");console.log(reg);return reg.test(obj.className);}//删除指定类function removeClass(obj, cn){var reg = new RegExp("\\b"+ cn +"\\b");obj.className = obj.className.replace(reg, "");}/* toggleClass可以用来切换一个类如果元素中具有该类,则删除如果元素中没有该类,则添加*/function toggleClass(obj, cn){if(hasClass(obj, cn)){removeClass(obj, cn);}else{addClass(obj, cn);}}
希望本练习对你有所帮助,加油!
如果觉得《HTML/CSS/JS制作网页中的二级下拉菜单》对你有帮助,请点赞、收藏,并留下你的观点哦!