如何在删除Input标签后动态更新其class与Title属性以维持顺序
动态表单输入项删除后自动更新顺序的解决方案
核心思路
- 放弃依赖独立计数器维护顺序,改为每次添加/删除操作后,遍历目标容器内的所有额外输入项,根据实际位置索引重新计算
title和class - 提取通用更新函数,统一处理不同类型输入框(日期、星期)的顺序校正
- 单次绑定删除事件,避免重复绑定导致的逻辑混乱
修改后完整代码
JavaScript 部分
let addMoreInputs = document.querySelectorAll('.addMoreInputs') let fieldTags = ['Second', 'Third', 'Fourth', 'Fifth', 'Sixth'] // 通用更新字段顺序的函数 function updateFieldOrder(container, inputType) { const inputWrappers = container.querySelectorAll('.relative.flex.items-center.w-full') inputWrappers.forEach((wrapper, index) => { const inputElement = wrapper.querySelector(`#${inputType}`) if (!inputElement || !fieldTags[index]) return // 根据索引更新title if (inputType === 'startDate') { inputElement.title = `${fieldTags[index]} Start Date` // 若需要带顺序的class,可在此添加: // inputElement.classList.add(`${fieldTags[index].toLowerCase()}StartDate`) } else if (inputType === 'aptDay') { inputElement.title = `${fieldTags[index]} Appointment Start Day` } }) } for (let addMore of addMoreInputs) { addMore.onclick = () => { // 更可靠地获取输入类型和目标容器 const defaultInput = addMore.closest('.default').querySelector('input, select') const inputType = defaultInput.id const moreDetails = addMore.closest('.relative.h-fit').querySelector('.addSections') // 生成对应输入项HTML let inputHtml = '' if (inputType === 'startDate') { inputHtml = ` <input type="date" placeholder="Start Date" name="dates" aria-autocomplete="none" autocomplete="off" id="startDate" class="startDate placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest" /> ` } else if (inputType === 'aptDay') { inputHtml = ` <select name="aptDay" id="aptDay" class="aptDay placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest"> <option value="" class="text-xs md:font-semibold md:text-xs">Pick a day</option> <option value="Monday" class="text-xs md:font-semibold md:text-xs">Monday</option> <option value="Tuesday" class="text-xs md:font-semibold md:text-xs">Tuesday</option> <option value="Wednesday" class="text-xs md:font-semibold md:text-xs">Wednesday</option> <option value="Thursday" class="text-xs md:font-semibold md:text-xs">Thursday</option> <option value="Friday" class="text-xs md:font-semibold md:text-xs">Friday</option> <option value="Saturday" class="text-xs md:font-semibold md:text-xs">Saturday</option> <option value="Sunday" class="text-xs md:font-semibold md:text-xs">Sunday</option> </select> ` } // 创建输入项包装元素 const inputWrapper = document.createElement('div') inputWrapper.classList.add('relative', 'flex', 'items-center', 'w-full') const inputHolder = document.createElement('div') inputHolder.classList.add('w-full') inputHolder.innerHTML = inputHtml const deleteDateInput = document.createElement('span') deleteDateInput.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 p-1 rounded-full text-rose-600 ml-2 deleteExtraDateInput cursor-pointer ease-in-out duration-300"> <path fill-rule="evenodd" d="M16.5 4.478v.227a48.816 48.816 0 013.878.512.75.75 0 11-.256 1.478l-.209-.035-1.005 13.07a3 3 0 01-2.991 2.77H8.084a3 3 0 01-2.991-2.77L4.087 6.66l-.209.035a.75.75 0 01-.256-1.478A48.567 48.567 0 017.5 4.705v-.227c0-1.564 1.213-2.9 2.816-2.951a52.662 52.662 0 013.369 0c1.603.051 2.815 1.387 2.815 2.951zm-6.136-1.452a51.196 51.196 0 013.273 0C14.39 3.05 15 3.684 15 4.478v.113a49.488 49.488 0 00-6 0v-.113c0-.794.609-1.428 1.364-1.452zm-.355 5.945a.75.75 0 10-1.5.058l.347 9a.75.75 0 101.499-.058l-.346-9zm5.48.058a.75.75 0 10-1.498-.058l-.347 9a.75.75 0 001.5.058l.345-9z" clip-rule="evenodd" /> </svg> ` // 单次绑定删除事件 deleteDateInput.querySelector('.deleteExtraDateInput').onclick = () => { inputWrapper.remove() // 删除后立即更新剩余项顺序 updateFieldOrder(moreDetails, inputType) } // 组装并添加到容器 inputWrapper.appendChild(inputHolder) inputWrapper.appendChild(deleteDateInput) moreDetails.appendChild(inputWrapper) // 添加后立即更新顺序 updateFieldOrder(moreDetails, inputType) } }
HTML 部分(无需修改)
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" /> <div class="categoryFields md:grid md:grid-cols-1 md:gap-x-10"> <!-- Start Date --> <div class="relative h-fit flex flex-col startDateWrapper"> <div class="default w-full flex items-center"> <div class="grow relative"> <input type="date" placeholder="Start Date" name="dates" aria-autocomplete="none" autocomplete="off" id="startDate" title="Appointment Start Date" class="aptStartDate placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest" /> </div> <div class="addMoreInputs ml-5 cursor-pointer"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 text-indigo-600"> <path fill-rule="evenodd" d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zM12.75 9a.75.75 0 00-1.5 0v2.25H9a.75.75 0 000 1.5h2.25V15a.75.75 0 001.5 0v-2.25H15a.75.75 0 000-1.5h-2.25V9z" clip-rule="evenodd" /> </svg> </div> </div> <div class="additionalDates addSections grid grid-cols-1 gap-x-10" name="Appointment Start Date"> </div> </div> <!-- Start Day --> <div class="relative h-fit flex flex-col"> <div class="default w-full flex items-center"> <div class="grow relative"> <select name="days" id="aptDay" title="Appointment Start Day" class="aptDay placeholder-transparent peer w-full my-5 h-12 text-xs font-semibold uppercase text-indigo-600 border border-indigo-600 rounded-md tracking-widest"> <option value="" class="text-xs md:font-semibold md:text-xs"> Pick a day </option> <option value="Monday" class="text-xs md:font-semibold md:text-xs"> Monday </option> <option value="Tuesday" class="text-xs md:font-semibold md:text-xs"> Tuesday </option> <option value="Wednesday" class="text-xs md:font-semibold md:text-xs"> Wednesday </option> <option value="Thursday" class="text-xs md:font-semibold md:text-xs"> Thursday </option> <option value="Friday" class="text-xs md:font-semibold md:text-xs"> Friday </option> <option value="Saturday" class="text-xs md:font-semibold md:text-xs"> Saturday </option> <option value="Sunday" class="text-xs md:font-semibold md:text-xs"> Sunday </option> </select> </div> <div class="addMoreInputs ml-5 cursor-pointer"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6 text-indigo-600"> <path fill-rule="evenodd" d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zM12.75 9a.75.75 0 00-1.5 0v2.25H9a.75.75 0 000 1.5h2.25V15a.75.75 0 001.5 0v-2.25H15a.75.75 0 000-1.5h-2.25V9z" clip-rule="evenodd" /> </svg> </div> </div> <div class="additionalDay addSections grid grid-cols-1 gap-x-10" name="Appointment Start Day"> </div> </div> </div>
关键改动说明
updateFieldOrder函数:遍历容器内所有输入项,根据位置索引匹配fieldTags文本,动态更新title(如需带顺序的class可在此扩展)- DOM选择优化:用
closest和querySelector替代childNodes,避免文本节点导致的索引错误,代码更健壮 - 删除事件单次绑定:创建删除按钮时直接绑定事件,避免重复绑定导致的多次触发问题
- 实时更新机制:添加/删除操作后立即调用
updateFieldOrder,确保所有输入项的顺序始终保持正确
内容的提问来源于stack exchange,提问作者alittlecurryhot
相关产品推荐
相关产品推荐

