通过data-id获取选中输入框的textarea值,动态追加元素失效问题
问题描述

我可以从第一个service下拉框(选中状态)的data-id属性中获取对应Description(textarea)的值(这部分正常),但点击Add more按钮追加元素后,无法获取新元素的对应值。
请问我遗漏了什么?
以下是我的代码:
HTML代码
<div class="service-box"> <div class="row"> <div class="col-md-12 service-group"> <div class="row"> <div class="form-group mb-3 col-md-6"> <label class="form-label">Service</label> <div> <select type="text" class="form-select" placeholder="Services" value="" name="service" id="service"> <option value="" disabled selected>Select your option</option> @foreach ($services as $service) <option value="{{$service->service_name}}" data-id="{{$service->description}}">{{$service->service_name}}</option> @endforeach </select> </div> </div> <div class="form-group mb-3 col-md-6"> <label class="form-label">Amount</label> <div> <input type="text" class="form-control" name="amount" id="amount" placeholder="Amount"> </div> </div> <div class="form-group mb-3 col-md-12"> <label class="form-label">Description</label> <textarea class="form-control" id="description" name="description" rows="6" placeholder="Content.." readonly></textarea> </div> </div> </div> </div> </div> <div class="col-md-12"> <button type="button" id="addmore" class="btn btn-default">Add more</button> <button type="button" id="remove" class="btn btn-default">Remove</button> </div>
JavaScript代码
$("#addmore").click(function() { var serviceGroupHTML = $('.service-group').html(); $( ".service-box" ).append(serviceGroupHTML); }); $("#remove").on("click", function() { $(".service-box").children().last().remove(); }); <!-- 问题出在这里 --> const service = new Array(document.getElementById("service")); const description = new Array(document.getElementById("description")); service[0].addEventListener("change", function(){ description[0].value = $('#service option:selected').data('id'); }) service[1].addEventListener("change", function(){ description[1].value = $('#service option:selected').data('id'); })
解决方案
你遇到的问题主要来自三个方面,修改后即可解决:
1. 移除重复ID,改用类名
页面中ID必须唯一,你复制的HTML会生成多个id="service"、id="description",浏览器只会识别第一个匹配的元素,导致新添加的元素无法被选中。把所有重复ID改成类名:
修改后的核心HTML片段:
<select type="text" class="form-select service-select" placeholder="Services" value="" name="service"> <!-- ... --> <input type="text" class="form-control amount-input" name="amount" placeholder="Amount"> <!-- ... --> <textarea class="form-control description-textarea" name="description" rows="6" placeholder="Content.." readonly></textarea>
2. 使用事件委托处理动态元素
你只给第一个下拉框绑定了change事件,动态添加的元素没有绑定事件。利用事件委托,把事件绑定到父元素上,就能处理所有现有和新增的元素:
3. 修正选择器,关联当前分组的元素
$('#service option:selected')只会选中第一个下拉框的选项,要改成相对当前下拉框的选择,确保每个下拉框只更新自己分组内的描述框。
修改后的完整JavaScript代码
$("#addmore").click(function() { // 复制第一个完整的service-group元素,而非仅内部HTML var serviceGroup = $('.service-group').first().clone(); // 清空复制的输入框内容,避免重复数据 serviceGroup.find('.service-select').val(''); serviceGroup.find('.amount-input').val(''); serviceGroup.find('.description-textarea').val(''); $(".service-box").append(serviceGroup); }); $("#remove").on("click", function() { // 至少保留一个分组,防止全部删除 if ($('.service-group').length > 1) { $(".service-box").find('.service-group').last().remove(); } }); // 事件委托:绑定到父元素,监听所有.service-select的change事件 $('.service-box').on('change', '.service-select', function() { // 获取当前下拉框选中选项的data-id var selectedDesc = $(this).find('option:selected').data('id'); // 找到当前分组内的描述框,设置值 $(this).closest('.service-group').find('.description-textarea').val(selectedDesc); });
关键修改说明
- 使用
clone()复制整个分组元素,比复制HTML更稳定,同时清空输入框避免数据重复; - 事件委托通过父元素
service-box监听子元素的change事件,动态添加的元素也能触发; - 用
closest('.service-group')定位当前下拉框所在的分组,确保每个下拉框只对应自己的描述框; - 添加删除判断,防止删除所有分组。
内容的提问来源于stack exchange,提问作者devsam247
相关产品推荐
相关产品推荐

