You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

双酒店预订表单客人选择弹窗失效问题求助

解决酒店预订表单模块客人数量弹窗冲突问题

嘿,我帮你捋清楚这个问题——核心就是重复的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());
}

为什么这样改就没问题了?

  1. 唯一ID/Name:每个模块的ID和表单name都是唯一的,不会出现JS选到错误元素的情况。
  2. 相对选择器:不再用全局选择器找元素,而是从当前点击的容器出发,只操作自己模块内的弹窗、输入框和下拉框,两个模块彻底独立。
  3. 独立事件绑定:通过each()遍历每个模块,给每个模块单独绑定事件,不会出现点击A模块触发B模块事件的情况。

这样修改之后,两个表单的客人数量弹窗就能各自正常工作啦~

内容的提问来源于stack exchange,提问作者lonelydev101

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:26:39