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

JQuery问题:仅最后添加的元素功能正常,求解决方案

问题描述

我有一个项目列表,点击模态框(Modal)可以打开并修改详情。其中设置了一个select选择框,选中选项时会追加HTML内容,但目前遇到的问题是:该select对应的JQuery逻辑仅对最后添加的项生效。


相关代码

HTML 代码

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="fullCalModal1" class="modal fade pull-left" style="align-content: center">
  <div class="modal-dialog" style="float:left; margin-right: 1500px">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span>
        <span class="sr-only">close</span>
        </button>
        <h4 id="modalTitle" class="modal-title" style="color: #4caf50">
        <b>{{$order->title}}</b></h4>
      </div>
      <div id="modalBody" class="modal-body col-md-12">
        <div class="col-md-6">
          <center><button type="button" class="btn btn-flat btn-success btn-md set" style="margin-bottom:50px;">SET DETAILS</button>
          </center>
          <div class="askq" hidden>
            <label style="float:center; font-size:15px; color:black">
            <b>&nbsp;Mode of Delivery:</b></label>
            <select name="mode" class="mode form-control" id="mode">
            <option value="Delivery">Delivery</option>
            <option value="Pickup">Pick up</option>
            </select>
            <div class="address" id="address"></div>
            <label style="float:center; font-size:15px; color:black">
            <b>&nbsp;Do you have any specifications?</b></label>
            <input type='text' name="spec" class='form-control has-success' style='width:250px'>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="submit" class="btn btn-success"><a id="eventUrl" style="color:white" target="_blank">Save Changes</a></button>
      </div>
    </div>
  </div>
</div>

<div id="fullCalModal2" class="modal fade pull-left" style="align-content: center">
  <div class="modal-dialog" style="float:left; margin-right: 1500px">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span>
        <span class="sr-only">close</span>
        </button>
        <h4 id="modalTitle" class="modal-title" style="color: #4caf50">
        <b>{{$order->title}}</b></h4>
      </div>
      <div id="modalBody" class="modal-body col-md-12">
        <div class="col-md-6">
          <center><button type="button" class="btn btn-flat btn-success btn-md set" style="margin-bottom:50px;">SET DETAILS</button>
          </center>
          <div class="askq" hidden>
            <label style="float:center; font-size:15px; color:black">
            <b>&nbsp;Mode of Delivery:</b></label>
            <select name="mode" class="mode form-control" id="mode">
            <option value="Delivery">Delivery</option>
            <option value="Pickup">Pick up</option>
            </select>
            <div class="address" id="address"></div>
            <label style="float:center; font-size:15px; color:black">
            <b>&nbsp;Do you have any specifications?</b></label>
            <input type='text' name="spec" class='form-control has-success' style='width:250px'>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="submit" class="btn btn-success"><a id="eventUrl" style="color:white" target="_blank">Save Changes</a></button>
      </div>
    </div>
  </div>
</div>

JavaScript 代码

$(document).ready(function(){
 $('.set').click(function(){
 $('.askq').removeAttr('hidden');
 $(this).attr('disabled', 'disabled');
 });
 $('.mode').change(function(e){
 e.preventDefault();
 var val = $(".mode option:selected").val();
 var div = document.getElementById('address');
 console.log(val);
 if(val=="Delivery"){
 div.innerHTML="<label style='float:center; font-size:15px; color:black'><b>&nbsp;Delivery Address:</b></label><input type='text' name='d_address' class='form-control has-success' id='defadd' style='width:250px' value='{{$order->location}}'><input type='checkbox' class='defaultadd' id='defaultadd' checked>&nbsp;Use default address";
 } else {
 div.innerHTML="<label><label style='float:center; font-size:15px; color:black'><b>&nbsp;Pick-Up Address:</b></label>&nbsp;<label>{{$order->c_location}}</label><input type='hidden' name='p_address' value='{{$order->c_location}}'>";
 }
 $(".defaultadd").change(function(){
 if ($(".defaultadd").is(":checked")){
 // $select.removeAttr('disabled');
 $('#defadd').val('{{$order->location}}');
 }else{
 $('#defadd').val('');
 $('#defadd').attr('placeholder', 'Please choose delivery location')
 // $select.attr('disabled','disabled');
 }
 });
 });
});

问题原因与解决方案

核心问题分析

你遇到的问题主要来自两个关键点:

  1. 重复ID冲突:HTML规范要求ID必须是唯一的,但你每个模态框里的mode、address、defadd、defaultadd都用了相同的ID。当你用document.getElementById或$('#xxx')选择元素时,浏览器只会返回最后一个匹配该ID的元素,这就是为什么只有最后一个模态框的逻辑能正常工作。
  2. 事件绑定的作用域问题:每次触发mode的change事件时,你都会重新绑定defaultadd的change事件,而且绑定的事件没有限定在当前模态框内,依然会全局选择元素,导致事件重复绑定且作用对象错误。

修复后的完整代码

第一步:调整HTML(移除重复ID)

把所有重复的ID替换成类名,确保每个元素的选择都是基于当前模态框的上下文:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- 第一个模态框 -->
<div id="fullCalModal1" class="modal fade pull-left" style="align-content: center">
  <div class="modal-dialog" style="float:left; margin-right: 1500px">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span>
        <span class="sr-only">close</span>
        </button>
        <h4 class="modal-title" style="color: #4caf50">
        <b>{{$order->title}}</b></h4>
      </div>
      <div class="modal-body col-md-12">
        <div class="col-md-6">
          <center><button type="button" class="btn btn-flat btn-success btn-md set" style="margin-bottom:50px;">SET DETAILS</button>
          </center>
          <div class="askq" hidden>
            <label style="float:center; font-size:15px; color:black">
            <b>&nbsp;Mode of Delivery:</b></label>
            <select name="mode" class="mode form-control">
            <option value="Delivery">Delivery</option>
            <option value="Pickup">Pick up</option>
            </select>
            <div class="address"></div>
            <label style="float:center; font-size:15px; color:black">
            <b>&nbsp;Do you have any specifications?</b></label>
            <input type='text' name="spec" class='form-control has-success' style='width:250px'>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="submit" class="btn btn-success"><a style="color:white" target="_blank">Save Changes</a></button>
      </div>
    </div>
  </div>
</div>

<!-- 第二个模态框 -->
<div id="fullCalModal2" class="modal fade pull-left" style="align-content: center">
  <div class="modal-dialog" style="float:left; margin-right: 1500px">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span>
        <span class="sr-only">close</span>
        </button>
        <h4 class="modal-title" style="color: #4caf50">
        <b>{{$order->title}}</b></h4>
      </div>
      <div class="modal-body col-md-12">
        <div class="col-md-6">
          <center><button type="button" class="btn btn-flat btn-success btn-md set" style="margin-bottom:50px;">SET DETAILS</button>
          </center>
          <div class="askq" hidden>
            <label style="float:center; font-size:15px; color:black">
            <b>&nbsp;Mode of Delivery:</b></label>
            <select name="mode" class="mode form-control">
            <option value="Delivery">Delivery</option>
            <option value="Pickup">Pick up</option>
            </select>
            <div class="address"></div>
            <label style="float:center; font-size:15px; color:black">
            <b>&nbsp;Do you have any specifications?</b></label>
            <input type='text' name="spec" class='form-control has-success' style='width:250px'>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="submit" class="btn btn-success"><a style="color:white" target="_blank">Save Changes</a></button>
      </div>
    </div>
  </div>
</div>

第二步:修改JavaScript(使用事件委托+相对选择器)

利用jQuery的事件委托处理动态生成的元素,同时通过$(this)和closest()来定位当前模态框内的元素,确保操作的是当前上下文的内容:

$(document).ready(function(){
    // 点击SET DETAILS按钮,显示当前模态框内的表单
    $('.set').click(function(){
        $(this).closest('.modal-body').find('.askq').removeAttr('hidden');
        $(this).attr('disabled', 'disabled');
    });

    // 委托处理所有mode选择框的change事件(包括动态生成的)
    $(document).on('change', '.mode', function(e){
        e.preventDefault();
        const $currentSelect = $(this);
        const selectedVal = $currentSelect.val();
        // 找到当前选择框所在的askq容器下的address元素
        const $addressContainer = $currentSelect.closest('.askq').find('.address');

        if(selectedVal === "Delivery"){
            $addressContainer.html(`
                <label style='float:center; font-size:15px; color:black'><b>&nbsp;Delivery Address:</b></label>
                <input type='text' name='d_address' class='form-control has-success defadd' style='width:250px' value='{{$order->location}}'>
                <input type='checkbox' class='defaultadd' checked>&nbsp;Use default address
            `);
        } else {
            $addressContainer.html(`
                <label style='float:center; font-size:15px; color:black'><b>&nbsp;Pick-Up Address:</b></label>
                &nbsp;<label>{{$order->c_location}}</label>
                <input type='hidden' name='p_address' value='{{$order->c_location}}'>
            `);
        }
    });

    // 委托处理所有defaultadd复选框的change事件(动态生成元素必须用委托)
    $(document).on('change', '.defaultadd', function(){
        const $currentCheckbox = $(this);
        // 找到当前复选框所在askq容器下的defadd输入框
        const $deliveryInput = $currentCheckbox.closest('.askq').find('.defadd');
        
        if ($currentCheckbox.is(":checked")){
            $deliveryInput.val('{{$order->location}}');
        } else {
            $deliveryInput.val('').attr('placeholder', 'Please choose delivery location');
        }
    });
});

额外优化建议

  • 把内联样式提取到单独的CSS文件中,方便统一维护和修改。
  • 如果后续要生成更多模态框,建议使用模板引擎(比如Laravel的Blade模板循环)来批量生成,避免重复写冗余的HTML代码。
  • 可以给每个模态框添加data-*属性来存储订单的专属数据(比如data-location="{{$order->location}}"),这样在JS中可以通过$currentModal.data('location')获取,不用依赖模板变量的重复渲染,更灵活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:25:37