双酒店预订表单客人选择弹窗失效问题求助
解决酒店预订表单模块客人数量弹窗冲突问题
嘿,我帮你捋清楚这个问题——核心就是重复的ID加上JS里全局选择器导致的事件绑定混乱,咱们一步步来修复:
先搞定HTML的问题:补全结构+唯一ID
首先你第二个模块的客人选择弹窗结构是缺失的,而且两个模块里的guests、number这些ID都是重复的(ID在页面里必须唯一!),先把这些改了:
第一个铂金模块的客人区域调整:
<li class="hb-form-field hb-form-number"> <div class="label">Number</div> <!-- 把id改成guests-platinum,唯一标识 --> <div id="guests-platinum" class="hb-form-field-input hb_input_field"> <!-- 数量输入框id改成number-platinum --> <input type="text" id="number-platinum" class="day" value="01" /> <input class="month" type="text" value="Guests" /> </div> <div class="hb-form-field-list"> <div class="hb-form-field-input hb-guest-field"> <!-- 下拉框name改成adults_capacity_platinum,避免和第二个模块冲突 --> <select name="adults_capacity_platinum" tabindex="-1" aria-hidden="true"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> <option value="6">6</option> <option value="7">7</option> <option value="8">8</option> <option value="9">9</option> </select> <span class="name">Guests</span> <span class="number-icons goUp"><i class="ion-plus"></i></span> <span class="number-icons goDown"><i class="ion-minus"></i></span> </div> </div> </li>
第二个黄金模块的客人区域补全+调整:
你之前第二个模块没写客人弹窗的结构,先补上,同时把ID改成唯一值:
<li class="hb-form-field hb-form-number"> <div class="label">Number</div> <!-- 唯一id:guests-gold --> <div id="guests-gold" class="hb-form-field-input hb_input_field"> <!-- 数量输入框id:number-gold --> <input type="text" id="number-gold" class="day" value="01" /> <input class="month" type="text" value="Guests" /> </div> <!-- 补上缺失的弹窗结构 --> <div class="hb-form-field-list"> <div class="hb-form-field-input hb-guest-field"> <!-- 下拉框name:adults_capacity_gold --> <select name="adults_capacity_gold" tabindex="-1" aria-hidden="true"> <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> <option value="6">6</option> <option value="7">7</option> <option value="8">8</option> <option value="9">9</option> </select> <span class="name">Guests</span> <span class="number-icons goUp"><i class="ion-plus"></i></span> <span class="number-icons goDown"><i class="ion-minus"></i></span> </div> </div> </li>
再重构JS:用相对选择器让每个模块独立工作
原来的JS代码用了全局选择器,比如$('#guests')会直接选中第一个模块的元素,$('.sc-hb-rooms-search.style-01 .hb-form-field-list')会选中所有模块的弹窗,导致点击一个模块会影响另一个。咱们改成针对每个模块内部的元素操作:
// 遍历所有带guests-前缀的容器,给每个模块单独绑定事件 $('[id^="guests-"]').each(function () { // 当前模块的客人点击容器 const $guestBox = $(this); // 找到当前模块里的弹窗列表(用closest往上找父级,再find子元素,只找当前模块内的) const $popupList = $guestBox.closest('.hb-form-table').find('.hb-form-field-list'); // 当前模块的数量显示输入框 const $numberInput = $guestBox.find('.day'); // 当前模块的客人数量下拉框 const $adultsSelect = $popupList.find('select[name^="adults_capacity"]'); // 点击客人区域,切换弹窗显示/隐藏 $guestBox.on('click touch', function () { $popupList.toggleClass('active'); }); // 点击页面其他地方,关闭当前模块的弹窗 $(document).on('click touch', function (event) { // 判断点击的元素不是当前客人容器,也不是它的子元素 if (!$guestBox.is(event.target) && !$guestBox.has(event.target).length) { $popupList.removeClass('active'); } }); // 阻止弹窗内部的点击事件冒泡到document,避免弹窗自己关闭 $popupList.on('click touch', function (event) { event.stopPropagation(); }); // 点击+号,增加客人数量 $popupList.find('.goUp').on('click', function () { const currentIndex = $adultsSelect.find('option:selected').index(); const totalOptions = $adultsSelect.find('option').length; // 已经到最大数量了,就不操作 if (currentIndex + 1 >= totalOptions) return; // 选中下一个选项 const nextValue = $adultsSelect.find('option').eq(currentIndex + 1).val(); $adultsSelect.val(nextValue); // 更新显示的数字 updateNumber($numberInput, $adultsSelect); }); // 点击-号,减少客人数量 $popupList.find('.goDown').on('click', function () { const currentIndex = $adultsSelect.find('option:selected').index(); // 已经是最小数量了,就不操作 if (currentIndex <= 0) return; // 选中上一个选项 const prevValue = $adultsSelect.find('option').eq(currentIndex - 1).val(); $adultsSelect.val(prevValue); // 更新显示的数字 updateNumber($numberInput, $adultsSelect); }); }); // 单独写更新数字显示的函数,针对当前模块的元素 function updateNumber($input, $select) { const count = parseInt($select.find('option:selected').text()); // 小于10的话前面加0,比如01、02 $input.val(count < 10 ? `0${count}` : count.toString()); }
为什么这样改就没问题了?
- 唯一ID/Name:每个模块的ID和表单name都是唯一的,不会出现JS选到错误元素的情况。
- 相对选择器:不再用全局选择器找元素,而是从当前点击的容器出发,只操作自己模块内的弹窗、输入框和下拉框,两个模块彻底独立。
- 独立事件绑定:通过
each()遍历每个模块,给每个模块单独绑定事件,不会出现点击A模块触发B模块事件的情况。
这样修改之后,两个表单的客人数量弹窗就能各自正常工作啦~
内容的提问来源于stack exchange,提问作者lonelydev101
相关产品推荐
相关产品推荐

