如何实现点击页面其他区域时关闭下拉菜单

如何实现点击页面其他区域时关闭下拉菜单

第一段引用上面的摘要:

本文旨在提供一种简洁有效的方案,实现点击页面 body 区域时关闭下拉菜单的功能。我们将分析原生 JavaScript 实现方案中存在的问题,并介绍如何使用 jquery 简化代码,实现更可靠的下拉菜单控制。通过本文,你将掌握一种常用的前端交互技巧,提升用户体验。

在 Web 开发中,下拉菜单是一种常见的交互元素。通常,我们希望用户在点击菜单以外的区域时,自动关闭下拉菜单。本文将探讨如何使用 JavaScript(包括原生 JavaScript 和 jQuery)来实现这一功能,并分析不同方案的优缺点。

原生 JavaScript 实现方案分析

最初的代码尝试使用 window.onclick 事件来检测点击事件,并移除 .menu 元素的 show 类。然而,这段代码存在一些问题,导致无法正常工作:

  1. 事件覆盖: window.onclick 会覆盖之前绑定的事件处理程序。如果页面上还有其他依赖 window.onclick 的代码,可能会导致冲突。
  2. 逻辑错误: if (!(Event.target == titleElem.nextElementSibling.classList.contains(‘show’))) 这段逻辑判断存在问题,它检查的是点击目标是否是 .dropdown–title 元素的下一个兄弟元素,并且这个兄弟元素是否包含 show 类。这并不能正确判断点击是否发生在下拉菜单之外。

使用 jQuery 实现更可靠的方案

jQuery 提供了一种更简洁、更可靠的方式来处理 dom 事件。以下是使用 jQuery 实现点击 body 区域关闭下拉菜单的示例代码:

$(document).ready(function() {   $(document).on('click', function(event) {     if (!$(event.target).closest('.dropdown').Length) {       $('.categories.menu').removeClass('show');     }   }); });

代码解释:

  1. $(document).ready(function() { … });:确保在 DOM 加载完成后执行代码。
  2. $(document).on(‘click’, function(event) { … });:将点击事件绑定到 document 对象上,利用事件委托机制,可以监听整个文档的点击事件。
  3. $(event.target).closest(‘.dropdown’).length:使用 closest() 方法查找点击目标及其父元素中是否存在 .dropdown 元素。如果存在,则返回一个包含该元素的 jQuery 对象,其 length 属性大于 0;否则,返回一个空 jQuery 对象,其 length 属性为 0。
  4. if (!$(event.target).closest(‘.dropdown’).length):判断点击是否发生在 .dropdown 元素之外。
  5. $(‘.categories.menu’).removeClass(‘show’);:如果点击发生在 .dropdown 元素之外,则移除 .categories.menu 元素的 show 类,从而关闭下拉菜单。

完整 html 结构示例:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="dropdown">   <div class="dropdown--title">Choose category</div>   <div class="categories menu">     <a href="#" data-category="[15,16,26,27]" class="clicked">All</a>     <a href="http://localhost/discount/product-category/other/" data-category="15">Other</a>     <a href="http://localhost/discount/product-category/electronics/" data-category="16">Electronics</a>     <a href="http://localhost/discount/product-category/sports/" data-category="26">Sports</a>     <a href="http://localhost/discount/product-category/toys/" data-category="27">Toys & Games</a>   </div> </div>

css 样式(保持不变):

.dropdown {   position: relative; }  .dropdown::before {   content: "+";   position: absolute;   width: 1.5rem;   height: 1.5rem;   top: 15px;   right: 0;   color: var(--cbl); }  .dropdown .dropdown--title {   padding: 0.75rem;   width: 100%;   cursor: pointer; }  .dropdown .menu {   cursor: pointer;   max-height: 0;   overflow: hidden;   display: flex;   flex-direction: column;   position: absolute;   z-index: 12;   width: 100%;   top: 45px;   right: 0;   background-color: var(--cwh);   transition: max-height 0.3s;   -webkit-transition: max-height 0.3s;   -moz-transition: max-height 0.3s;   -ms-transition: max-height 0.3s;   -o-transition: max-height 0.3s;   box-shadow: 0 3px 20px #ccc;   -webkit-box-shadow: 0 3px 20px #ccc;   -moz-box-shadow: 0 3px 20px #ccc; }  .dropdown .menu.show {   max-height: 20em !important; }  .dropdown .menu.show a {   color: var(--cbl);   opacity: 1;   transition: all 0.3s;   -webkit-transition: all 0.3s;   -moz-transition: all 0.3s;   -ms-transition: all 0.3s;   -o-transition: all 0.3s;   transform: translateX(0);   -webkit-transform: translateX(0);   -moz-transform: translateX(0);   -ms-transform: translateX(0);   -o-transform: translateX(0); }  .dropdown .menu a {   padding: 1rem;   opacity: 0;   color: var(--cbl);   transform: translateX(100%);   -webkit-transform: translateX(100%);   -moz-transform: translateX(100%);   -ms-transform: translateX(100%);   -o-transform: translateX(100%); }  .dropdown .menu a:nth-child(1) {   transition-delay: 0.2s; }  .dropdown .menu a:nth-child(2) {   transition-delay: 0.15s; }  .dropdown .menu a:nth-child(3) {   transition-delay: 0.1s; }  .dropdown .menu a:nth-child(4) {   transition-delay: 0.05s; }  .dropdown .menu a:nth-child(5) {   transition-delay: 0s; }  .dropdown .menu a:not(:last-child) {   border-bottom: 1px solid var(--cblo40); }  .dropdown .menu a:hover {   background: rgba(0, 0, 0, 0.2); }

注意事项

  • 确保正确引入 jQuery 库。
  • .dropdown 和 .categories.menu 类名需要与你的 HTML 结构保持一致。
  • 如果你的下拉菜单结构更复杂,可能需要调整 closest() 方法的选择器
  • 使用事件委托可以提高性能,特别是在页面上有大量元素时。

总结

本文介绍了如何使用 jQuery 实现点击页面 body 区域时关闭下拉菜单的功能。 通过使用 closest() 方法,我们可以轻松判断点击是否发生在下拉菜单之外,并采取相应的操作。 这种方法简洁、可靠,并且易于维护。 在实际开发中,可以根据具体需求进行适当的调整和优化。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享