本文作者:IMWeb 寒纱阁主 原文出处:IMWeb社区 未经同意,禁止转载
以前制作导航菜单,总要加许多id在HTML中,js代码也要将id挨个加上去,今日终于习得破解之法,不在用以前那种笨拙的方法了。
以下是HTML代码:
<body>
<nav id="navlist">
<ul>
<li class="fucaidan xiaoshi">前端开发</li >
<li class="fucaidan xiaoshi">后端开发</li >
<li class="fucaidan xiaoshi">移动开发</li >
<li class="fucaidan xiaoshi">数据库</li >
<li class="fucaidan xiaoshi">大数据</li >
<li class="fucaidan xiaoshi">运维&测试</li >
<li class="fucaidan xiaoshi">UI设计</li >
</ul>
<div class="zicaidan xiaoshi">
<h3>基础1</h3>
HTML/CSS JavaScript jQuery
</div>
<div class="zicaidan xiaoshi">
<h3>基础2</h3>
HTML/CSS JavaScript jQuery
</div>
<div class="zicaidan xiaoshi">
<h3>基础3</h3>
HTML/CSS JavaScript jQuery
</div>
<div class="zicaidan xiaoshi">
<h3>基础4</h3>
HTML/CSS JavaScript jQuery
</div>
<div class="zicaidan xiaoshi">
<h3>基础5</h3>
HTML/CSS JavaScript jQuery
</div>
<div class="zicaidan xiaoshi">
<h3>基础6</h3>
HTML/CSS JavaScript jQuery
</div>
<div class="zicaidan xiaoshi">
<h3>基础7</h3>
HTML/CSS JavaScript jQuery
</div>
</nav>
内容没有细做,以下是CSS代码:
<style>
ul{
list-style: none;
box-sizing: border-box;
padding: 15px 0;
padding-left: 15px;
border-radius: 10% 0 0 10%;
color: white;
background-color:#555;
width: 150px;
height: 320px;
}
ul li{
padding: 10px 10px;
cursor: pointer;
background-color: #555;
}
div{
box-shadow: 1px 0 2px #666;
background-color: #999;
color: white;
height: 318px;
width: 500px;
position: absolute;
left: 158px;
top: 17px;
padding-left: 20px;
display: none;
cursor: pointer;
}
</style>
js我使用了构造函数进行封装,这样可以有效的避免js中命名重复的问题,并且修改起来很方便,不需要在HTML中加入许多id,代码简洁了不少:
function navList(id){
var dad=document.getElementById(id);
var fucaidan=dad.getElementsByClassName('fucaidan');
var zicaidan=dad.getElementsByClassName('zicaidan');
var xiaoshi=dad.getElementsByClassName('xiaoshi');
var ul=dad.getElementsByTagName('ul');
}
new navList('navlist');
接下来将菜单的onmouse事件写入构造函数中就ok了,但在其中遇到了问题:
for(var i=0;i<fucaidan.length;i++){
fucaidan[i].addEventListener('mouseenter',function(){
zicaidan[i].style.display='block';
this.style.backgroundColor='#999';
});
我们知道,for循环的便利在上面的函数中并不是我们所想的那样,而是一个定值。那么该如何解决这个问题呢?
event.target
event.target可以指出当前鼠标所指的元素,我们可以利用这一点写一个函数:
function findIndex(target,list){
for(var i=0;i<list.length;i++){
if(target==list[i]) return i;
}
return -1;
}
该函数的返回值便是与所指父菜单相同的索引值:
for(var i=0;i<fucaidan.length;i++){
fucaidan[i].addEventListener('mouseenter',function(event){
var a=findIndex(event.target,fucaidan);
zicaidan[a].style.display='block';
this.style.backgroundColor='#999';
});
这样问题就得到了完美解决。
最后再附上完整js代码:
<script>
//利用构造函数进行封装,防止名字滥用,HTML动态添加
function navList(id){
var dad=document.getElementById(id);
var fucaidan=dad.getElementsByClassName('fucaidan');
var zicaidan=dad.getElementsByClassName('zicaidan');
var xiaoshi=dad.getElementsByClassName('xiaoshi');
var ul=dad.getElementsByTagName('ul');
//错误抛出,方便检查
if(fucaidan.length!=zicaidan.length) throw '父类菜单和子类菜单长度不匹配';
//检索与父菜单索引相同子菜单
function findIndex(target,list){
for(var i=0;i<list.length;i++){
if(target==list[i]) return i;
}
return -1;
}
//子菜单和父菜单onmouse样式
function appear(){
for(var i=0;i<fucaidan.length;i++){
fucaidan[i].addEventListener('mouseenter',function(event){
var a=findIndex(event.target,fucaidan);
zicaidan[a].style.display='block';
this.style.backgroundColor='#999';
});
fucaidan[i].addEventListener('mouseleave',function(event){
var a=findIndex(event.target,fucaidan);
zicaidan[a].style.display='none';
this.style.backgroundColor='#555';
zicaidan[a].onmouseenter=function(){
zicaidan[a].style.display='block';
fucaidan[a].style.backgroundColor='#999';
}
zicaidan[a].onmouseleave=function(){
zicaidan[a].style.display='none';
fucaidan[a].style.backgroundColor='#555';
}
});
}
}
appear();
}
new navList('navlist');
</script>
不妨在上面的导航菜单中加入轮播效果:
<script>
//利用构造函数进行封装,防止名字滥用,HTML动态添加
function navList(id){
var N=1;
var dad=document.getElementById(id);
var fucaidan=dad.getElementsByClassName('fucaidan');
var zicaidan=dad.getElementsByClassName('zicaidan');
var xiaoshi=dad.getElementsByClassName('xiaoshi');
var ul=dad.getElementsByTagName('ul');
//错误抛出,方便检查
if(fucaidan.length!=zicaidan.length) throw '父类菜单和子类菜单长度不匹配';
//设置菜单样式
function addStyle(a){
zicaidan[a].style.display='block';
fucaidan[a].style.backgroundColor='#999';
}
//清除菜单样式
function clearAll(){
for(var i=0;i<fucaidan.length;i++){
zicaidan[i].style.display='none';
fucaidan[i].style.backgroundColor='#555';
}
}
//检索与父菜单索引相同子菜单
function findIndex(target,list){
for(var i=0;i<list.length;i++){
if(target==list[i]) return i;
}
return -1;
}
//计时器
function timeList(){
clearAll();
zicaidan[N].style.display='block';
fucaidan[N].style.backgroundColor='#999';
N++;
if(N>fucaidan.length-1) N=0;
}
//计时器开始
var timeBegin=function(a){
zicaidan[a].style.display='block';
fucaidan[a].style.backgroundColor='#999';
N=a;
timing=setInterval(timeList,1000);
}
timeBegin(N-1);
//计时器停止
function timeEnd(){
for(var i=0;i<fucaidan.length;i++){
fucaidan[i].onmouseenter=function(){
clearInterval(timing);
zicaidan[N-1].style.display='none';
fucaidan[N-1].style.backgroundColor='#555';
}
zicaidan[i].onmouseenter=function(){
clearInterval(timing);
}
}
}
//子菜单和父菜单onmouse样式
this.appear=function(){
for(var i=0;i<fucaidan.length;i++){
fucaidan[i].addEventListener('mouseenter',function(event){
var a=findIndex(event.target,fucaidan);
clearInterval(timing);
clearAll();
addStyle(a);
});
zicaidan[i].addEventListener('mouseenter',function(event){
var a=findIndex(event.target,fucaidan);
clearInterval(timing);
addStyle(a);
});
zicaidan[i].addEventListener('mouseleave',function(event){
var a=findIndex(event.target,zicaidan);
timeBegin(a);
addStyle(a);
});
fucaidan[i].addEventListener('mouseleave',function(event){
var a=findIndex(event.target,fucaidan);
timeBegin(a);
addStyle(a);
zicaidan[a].onmouseenter=function(){
clearAll();
clearInterval(timing);
addStyle(a);
}
});
}
}
}
var navlist=new navList('navlist');
navlist.appear();
</script>