[英]Toggle dropdown menu on li but prevent toggle clicking on ul
在移動即時通訊上,使用javascript切換下拉菜單。 單擊列表項時,下拉列表應該可見,然后再次單擊切換回去。
問題:如果我想在下拉菜單中使用搜索欄,則該下拉菜單將切換回不可見的單擊狀態。
jQuery的:
$('.has-dropdown-two').on('click', function() {
$(this).toggleClass('is-active').children('ul').toggleClass('is-visible');
});
首先,我嘗試制作一個if子句,例如:
if ($(this).hasClass('nav-dropdown-two') ) ..
無法正常工作...然后我檢查了console.log(this),它看起來像單擊ul,它具有與單擊li時相同的輸出。
我做了一個非常簡單的預覽:
$('.has-dropdown-two').on('click', function() { var $this = $(this); $(this).toggleClass('is-active').children('ul').toggleClass('is-visible'); });
.has-dropdown-two > .menu-link { display: inline-block; } .has-dropdown-two.is-active > .nav-dropdown-two { display: block; } .nav-dropdown-two { display: none; position: absolute; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <li class="menu-item has-dropdown-two"> <a href="javascript:void(0);" class="menu-link stopnewline">Search</a> <ul class="nav-dropdown-two menu"> <div class="search-container"> <form action=""> <input type="text" name="search"> <button type="submit">search</button> </form> </div> </ul> </li>
根據lumio的解決方案進行編輯:
$('.has-dropdown-two').on('click', function(event) {
if ( event.target.tagName === 'A' || event.target.tagName === 'I' ) {
$(this).toggleClass('is-active').children('ul').toggleClass('is-visible');
}else{
return;
}
});
確實如mrdeadsven所述。 事件冒泡了。 這意味着,如果點擊事件發生在孩子身上,那么它也發生在父母身上。 除非得到預防。
您可以在<a>
標記上設置點擊處理程序,也可以通過將事件參數傳遞給事件處理程序功能來檢查實際單擊的內容。
$('.has-dropdown-two').on('click', function( event ) { // Check the tagName of clicked target element const tagName = event.target.tagName; if ( tagName === 'INPUT' || tagName === 'button' ) { return; } var $this = $(this); $(this).toggleClass('is-active').children('ul').toggleClass('is-visible'); });
.has-dropdown-two>.menu-link { display: inline-block; } .has-dropdown-two.is-active>.nav-dropdown-two { display: block; } .nav-dropdown-two { display: none; position: absolute; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <ul> <li class="menu-item has-dropdown-two"> <a href="javascript:void(0);" class="menu-link stopnewline">Search</a> <ul class="nav-dropdown-two menu"> <div class="search-container"> <form action=""> <input type="text" name="search"> <button type="submit">search</button> </form> </div> </ul> </li> </ul>
您可以很容易地完成上述示例,而無需使用jQuery。
另一個解決方案是檢查<a>
標記是否導致事件觸發。 這甚至可能是更好的解決方案,因為它也適用於嵌套子菜單。
const subMenuToggle = ( event ) => { // Only watch clicks on .toggle-switch if ( !event.target.classList.contains( 'toggle-switch' ) ) { return; } // Prevent the actual click on the link event.preventDefault(); // Toggle .is-active on parent <li> element const parent = event.target.parentNode; const className = 'is-active'; parent.classList.toggle( className ); // Only open the next direct ul parent.querySelectorAll( ':scope > ul' ).forEach( ( element ) => element.classList.toggle( className ) ); }; // Get all ul.navigation on the page document .querySelectorAll( '.navigation' ) .forEach( ( element ) => { element.addEventListener( 'click', subMenuToggle ); } );
.nav-dropdown-two { display: none; } .nav-dropdown-two.is-active { display: block; }
<!-- added .navigation for later --> <ul class="navigation"> <li class="menu-item has-dropdown-two"> <!-- added the .toggle-switch for the event listener --> <a href="#" class="toggle-switch">Search</a> <ul class="nav-dropdown-two menu"> <li> <div class="search-container"> <form action=""> <input type="text" name="search"> <button type="submit">search</button> </form> </div> </li> <li> <a href="#" class="toggle-switch">more</a> <ul class="nav-dropdown-two"> <li>Sub menu</li> </ul> </li> </ul> </li> </ul>
就像@mrdeadsven評論的一樣,這是由於事件傳播造成的 。
您可以通過將另一個偵聽器附加到表單並在其中調用event.stopPropagation()
來關閉它。
$('form').on('click', function(e){
e.stopPropagation();
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.