jQuery .show()正常工作但.hide()失效问题求助
问题
自定义图片下拉选择框,点击输入框时show()能正常展开下拉列表,但选择选项时hide()失效,元素的内联样式style="display: block;"毫无变化。
已尝试的操作:
- 将代码包裹在
$(document).ready(function()中 - 通过控制台确认JS能识别元素
display为block(可打印出"okokoko") - 确保jQuery在自定义JS文件之前加载
- 尝试用原生JS替代,均无效
相关代码如下:
JS代码
$('#ratingDropdownContainer').on('click', function() { if ($('.dropdown-list-container').css('display') == 'none') { $('.dropdown-list-container').show(); } }) $('.avg-rating-select').on('click', function() { var selectedRatingImg = $(this).find('img').prop('outerHTML'); var selectedRatingText = $(this).find('p').prop('outerHTML'); var newDiv = $("<div>" + selectedRatingImg + selectedRatingText + "</div>"); newDiv.addClass("rating-selected-container"); if ($('.rating-selected-container').length) { $('.rating-selected-container').replaceWith(newDiv); } else { $('.rating-dropdown-inner-text p').replaceWith(newDiv); } if ($('.dropdown-list-container').css('display') === 'block') { console.log("okokoko"); $('.dropdown-list-container').hide(); } })
HTML代码
<div class="col"> <div class="rating-dropdown-container" id="ratingDropdownContainer"> <div class="rating-dropdown-inner-text"> <p>Average Rating...</p> <i class="bi bi-caret-down-fill"></i> </div> <div class="dropdown-list-container" id="dropdownListContainer"> <ul class="rating-dropdown"> <li class="avg-rating-select"> <img src="/media/main/5stars.png" alt="5stars" class="avg-rating-select-img"> <p class="avg-rating-select-text">5 Stars & Up</p> </li> <li class="avg-rating-select"> <img src="/media/main/4stars.png" alt="4stars" class="avg-rating-select-img"> <p class="avg-rating-select-text">4 Stars & Up</p> </li> <li class="avg-rating-select"> <img src="/media/main/3stars.png" alt="3stars" class="avg-rating-select-img"> <p class="avg-rating-select-text">3 Stars & Up</p> </li> <li class="avg-rating-select"> <img src="/media/main/2stars.png" alt="2stars" class="avg-rating-select-img"> <p class="avg-rating-select-text">2 Stars & Up</p> </li> <li class="avg-rating-select"> <img src="/media/main/1stars.png" alt="1stars" class="avg-rating-select-img"> <p class="avg-rating-select-text">1 Star & Up</p> </li> </ul> </div> </div> </div>
CSS代码
.rating-dropdown-container { display: block; position: relative; width: 100%; padding: .375rem .75rem; font-size: 1rem; font-weight: 400; line-height: 1.5; color: #212529; background-color: #fff; background-clip: padding-box; border: 1px solid #ced4da; -webkit-appearance: none; -moz-appearance: none; appearance: none; border-radius: .375rem; transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out; } .dropdown-list-container { display: none; position: absolute; z-index: 100; border: 1px solid #ced4da; border-top:none; border-top-left-radius: 0; border-top-right-radius: 0; border-bottom-left-radius: .375rem; border-bottom-right-radius: .375rem; width: 100%; margin-left:-12px; background-color: #fff; } .avg-rating-select { padding-left: 8px; display: flex; align-items: center; cursor: pointer; }
(注:基于Bootstrap的Django项目)
解决方案
核心问题是事件冒泡:点击.avg-rating-select时,事件会向上传递到父元素#ratingDropdownContainer,触发它的点击事件。也就是说,你刚执行完hide(),父元素的点击事件又检测到下拉列表是none,立刻执行show(),所以看起来hide()没生效。
提供两种解决方法:
方法1:阻止事件冒泡
在.avg-rating-select的点击事件中添加event.stopPropagation(),阻止事件向上传递:
$('.avg-rating-select').on('click', function(event) { event.stopPropagation(); // 阻止事件冒泡到父元素 var selectedRatingImg = $(this).find('img').prop('outerHTML'); var selectedRatingText = $(this).find('p').prop('outerHTML'); var newDiv = $("<div>" + selectedRatingImg + selectedRatingText + "</div>"); newDiv.addClass("rating-selected-container"); if ($('.rating-selected-container').length) { $('.rating-selected-container').replaceWith(newDiv); } else { $('.rating-dropdown-inner-text p').replaceWith(newDiv); } $('.dropdown-list-container').hide(); // 无需再判断状态,直接隐藏 })
方法2:优化父元素点击逻辑
修改父元素的点击事件,仅在点击目标不是下拉列表本身时切换显示状态:
$('#ratingDropdownContainer').on('click', function(event) { // 点击区域不是下拉列表时才触发切换 if (!$(event.target).closest('.dropdown-list-container').length) { $('.dropdown-list-container').toggle(); } })
额外建议:统一使用ID选择器(比如#dropdownListContainer)代替类选择器,避免页面中存在多个相同类名元素时出现意外问题。
内容的提问来源于stack exchange,提问作者Hugh Mungus
相关产品推荐
相关产品推荐

