第一段引用上面的摘要:
本文旨在提供一种简洁有效的方案,实现点击页面 body 区域时关闭下拉菜单的功能。我们将分析原生 JavaScript 实现方案中存在的问题,并介绍如何使用 jquery 简化代码,实现更可靠的下拉菜单控制。通过本文,你将掌握一种常用的前端交互技巧,提升用户体验。
在 Web 开发中,下拉菜单是一种常见的交互元素。通常,我们希望用户在点击菜单以外的区域时,自动关闭下拉菜单。本文将探讨如何使用 JavaScript(包括原生 JavaScript 和 jQuery)来实现这一功能,并分析不同方案的优缺点。
原生 JavaScript 实现方案分析
最初的代码尝试使用 window.onclick 事件来检测点击事件,并移除 .menu 元素的 show 类。然而,这段代码存在一些问题,导致无法正常工作:
- 事件覆盖: window.onclick 会覆盖之前绑定的事件处理程序。如果页面上还有其他依赖 window.onclick 的代码,可能会导致冲突。
- 逻辑错误: 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'); } }); });
代码解释:
- $(document).ready(function() { … });:确保在 DOM 加载完成后执行代码。
- $(document).on(‘click’, function(event) { … });:将点击事件绑定到 document 对象上,利用事件委托机制,可以监听整个文档的点击事件。
- $(event.target).closest(‘.dropdown’).length:使用 closest() 方法查找点击目标及其父元素中是否存在 .dropdown 元素。如果存在,则返回一个包含该元素的 jQuery 对象,其 length 属性大于 0;否则,返回一个空 jQuery 对象,其 length 属性为 0。
- if (!$(event.target).closest(‘.dropdown’).length):判断点击是否发生在 .dropdown 元素之外。
- $(‘.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