如何實現以下的導航欄下拉菜單的效果
實現思路
(1) 用html與css渲染出下拉菜單(html 主要使用ul,li標簽來實現)
(2)用點擊事件去綁定所需要的dom元素,實現點擊就可以下拉菜單
(3)在考慮點擊下一個dom元素,使前一個下拉菜單消失
實現方法

1.用javaScript與jQuery實現
(1)html 的代碼如下
1 <!-- 導航欄 --> 2 <div class="top"> 3 <ul class="header-container"> 4 <li class='out'> 5 報名申請 6 <ul class="drop"> 7 <li>考級報名</li> 8 <li>創新創業報名</li> 9 </ul> 10 </li> 11 <li class='out'> 12 信息維護 13 <ul class="drop"> 14 <li>學生個人信息維護</li> 15 <li>專業方向確認</li> 16 </ul> 17 </li> 18 <li class='out'> 19 選課 20 <ul class="drop"> 21 <li>學生課表查詢</li> 22 </ul> 23 </li> 24 <li class='out'> 25 信息查詢 26 <ul class="drop"> 27 <li>查詢個人信息</li> 28 </ul> 29 </li> 30 <li class='out'> 31 教學評價 32 <ul class="drop"> 33 <li>問卷調查</li> 34 </ul> 35 </li> 36 </ul> 37 </div>
(2)css的代碼如下
1 html,body{ 2 margin:0; 3 width: 100%; 4 height:100%; 5 } 6 .top{ 7 width: 100%; 8 height: 60px; 9 background: linear-gradient(60deg,#e364f4, #e151f4); 10 display: flex; 11 justify-content: center; 12 align-items: center 13 /* background:linear-gradient(red 0%, orange 25%,green 75%, blue 100%); */ 14 } 15 .header-container{ 16 display: flex; 17 /* border: 1px solid #fff; */ 18 height: 100%; 19 justify-content: space-between; 20 align-items: center; 21 min-width: 800px; 22 max-width: 1200px; 23 margin: 0px; 24 list-style: none; 25 color: #fff; 26 padding: 0; 27 cursor: pointer; 28 transition: all .28s; 29 } 30 .header-container li{ 31 padding:0 20px 0 20px; 32 height: 100%; 33 line-height:60px; 34 position: relative; 35 } 36 37 li:hover{ 38 background:#e0dfdf ; 39 color:rgb(51, 49, 49) 40 } 41 li:active{ 42 background:#c3c3c3; 43 color:black 44 } 45 .drop{ 46 position: absolute; 47 width: 200px; 48 color:#000; 49 list-style: none; /* 去掉ul的樣式 */ 50 margin:0; 51 padding:0; 52 background: #fff; 53 border: 1px solid #E9E8F0; 54 display: none; 55 } 56 .show{ 57 display: block; 58 } 59 .drop li{ 60 font-size: 14px; 61 line-height: 40px; 62 position: relative; 63 }
上面的下拉菜單的出現與消失,主要是通過控制 <ul class="drop"></ul> class類名的增加與移除
(3) javaScript的代碼如下
1 /** 2 javascript 實現 3 */ 4 5 var outLi=document.querySelectorAll('.out'); 6 7 // 存儲前一次點擊的序號的數組 8 var param=[]; 9 10 // 為第一層ul的每一項li的index綁定一個值 11 for(let i=0;i<outLi.length;i++){ 12 outLi[i].index=i; 13 } 14 // 為第一層ul的每一項li的綁定監聽事件 15 for(let i=0;i<outLi.length;i++){ 16 // 監聽器 17 outLi[i].addEventListener('click',function(){ 18 // 阻止父元素的click事件 19 event.stopPropagation(); 20 if(param.length===1){ 21 // 獲取前一項的序號 22 var j=param[0]; 23 if(j===this.index){ 24 outLi[j].getElementsByClassName('drop')[0].classList.remove('show'); 25 // 清空數組 26 param=[]; 27 return 28 } 29 outLi[j].getElementsByClassName('drop')[0].classList.remove('show'); 30 // 清空數組 31 param=[]; 32 } 33 34 this.getElementsByClassName('drop')[0].classList.add('show') 35 36 param.push(this.index) 37 38 }) 39 } 40 41 document.getElementsByTagName('body')[0].addEventListener("click",function(){ 42 if(param.length!==0){ 43 var j=param[0]; 44 outLi[j].getElementsByClassName('drop')[0].classList.remove('show'); 45 param=[]; 46 47 } 48 })
下面這段代碼主要思路是,
通過param這個數組來判斷鼠標點擊當前的元素之前的有沒有點擊其他在這個導航欄的其他元素
如果有(數組的長度為1,表示數組有一項),假設點擊的項的index與數組存儲的值一樣,則代表元素兩次點擊同一項(默認為取消下拉菜單操作,不會再出現下來菜單,直接return,不會再執行下面的操作);
反之,不是同個值,則通過param的數組去取消下拉並清空數組,而當前click則出現下拉,並且當前的index進棧
if(param.length===1){ // 獲取前一項的序號 var j=param[0]; if(j===this.index){ outLi[j].getElementsByClassName('drop')[0].classList.remove('show'); // 清空數組 param=[]; return } outLi[j].getElementsByClassName('drop')[0].classList.remove('show'); // 清空數組 param=[]; } this.getElementsByClassName('drop')[0].classList.add('show') param.push(this.index)
注:this.getElementsByClassName('drop')[0].classList.add('show')中涉及到一個this的指向問題,在this的官方文檔中指出,若this作為一個dom事件處理的函數,this指向觸發事件的元素。
從這可以看出 點擊事件觸發的是outLi[i]的元素,所以this指向的元素是outLi[i]。
如果你想查詢更多有關this的問題,請訪問 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this
(4) jQuery的代碼如下
1 /** 2 jQuery 實現 3 */ 4 var $param=[] 5 6 $('.out').click(function(event){ 7 event.stopPropagation(); 8 var $index=$(this).index(); 9 if($param.length===1){ 10 if($param[0]===$index){ 11 $('.drop').eq($param[0]).removeClass('show'); 12 $param=[]; 13 return; 14 } 15 $('.drop').eq($param[0]).removeClass('show'); 16 $param=[]; 17 } 18 19 $('.drop').eq($index).addClass('show'); 20 $param.push($index) 21 // console.log($index) 22 console.log($param) 23 }) 24 25 26 27 $('body').click(function(){ 28 $show= $('.out').find('.show'); 29 $show.removeClass('show'); 30 31 })
由上可以看出,jQuery方法看上去比javaScript方便許多,主要是因為jQuery是javaScript的一個庫,所以用原生dom封裝了許多便利的方法
例如:javaScript需要我們自己給每一項li的lndex賦值,而jQuery封裝了index()方法,可以指定元素相對於其他指定元素的index值。還一個是eq() 放回帶有被選元素的指定索引值的元素
2. 用vue實現(css代碼如上)
1 <template> 2 <div class="home" @click="cancel"> 3 <!-- 導航欄 --> 4 <div class="top"> 5 <ul class="header-container"> 6 <li class='out' v-for="(item,index) in header" :key="index" @click.stop="drop(index)"> 7 {{item.tabTitle}} 8 <ul class="drop" > 9 <li v-for="(tip,index) in item.drop" :key="index" @click="jump(item.index,index)">{{tip}}</li> 10 </ul> 11 </li> 12 </ul> 13 </div> 14 </div> 15 </template>
js代碼部分
1 <script> 2 export default { 3 name: 'Home', 4 data(){ 5 return { 6 header:[ 7 { 8 tabTitle:"報名申請", 9 drop:['考證報名','創新創業報名'] 10 }, 11 { 12 tabTitle:"信息維護", 13 drop:['學生個人信息維護','專業方向確認'] 14 }, 15 { 16 tabTitle:"選課", 17 drop:['學生課表查詢'] 18 }, 19 { 20 tabTitle:"信息查詢", 21 drop:['查詢個人信息'] 22 }, 23 { 24 tabTitle:"教學評價", 25 drop:['問卷調查'] 26 } 27 ], 28 // 存儲前一個的數組 29 parmas:[] 30 } 31 }, 32 methods:{ 33 // 下拉菜單顯示 34 drop(index){ 35 var out=document.getElementsByClassName('out')[index]; 36 if(this.parmas.length===1){ 37 document.getElementsByClassName('out')[this.parmas[0]] 38 .getElementsByClassName('drop')[0].classList.remove('show'); 39 this.parmas=[] 40 } 41 out.getElementsByClassName('drop')[0].classList.add('show'); 42 this.parmas.push(index); 43 console.log(this.parmas) 44 }, 45 jump(itemIndex,TipIndex){ 46 console.log(itemIndex) 47 console.log(TipIndex) 48 }, 49 // 全局點擊取消下拉 50 cancel(){ 51 if(this.parmas.length!==0){ 52 document.getElementsByClassName('out')[this.parmas[0]] 53 .getElementsByClassName('drop')[0].classList.remove('show'); 54 } 55 } 56 } 57 } 58 </script>
實現方法的代碼與javaScript基本上一致的,區別在與html的渲染,采用的是vue所擁有的屬性,v-for渲染出來。
以上是作為小白的我實現下拉菜單,如果大家有更好的想法,可以評論分享下哈哈哈啊哈哈

