
本文介绍如何使用单一、可复用的 javascript 函数替代重复代码,实现对多个 bootstrap 模态框的统一控制,支持按需打开、关闭,并保持逻辑清晰、易于维护。
本文介绍如何使用单一、可复用的 javascript 函数替代重复代码,实现对多个 bootstrap 模态框的统一控制,支持按需打开、关闭,并保持逻辑清晰、易于维护。
在实际开发中,若为每个模态框(如“选择客户”“选择供应商”)单独编写独立的 setSelectedXXX() 函数,不仅造成大量冗余代码,还难以扩展与维护。更优解是抽象出通用逻辑:将模态框 ID 作为参数传入,由同一组函数统一管理显示、隐藏、数据回填与清理操作。
✅ 推荐方案:参数化模态框控制函数
以下是一个基于 jQuery + Bootstrap 的轻量级通用实现(兼容 Bootstrap 4/5):
<!-- 触发按钮:通过 data-modal-id 绑定目标模态框 -->
<button type="button" class="btn btn-primary open-modal" data-modal-id="pelanggan">选择客户</button>
<button type="button" class="btn btn-primary open-modal" data-modal-id="vendor">选择供应商</button>
<!-- 模态框模板(共用结构,仅 ID 和内容不同) -->
<div class="modal fade" id="pelanggan" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">选择客户</h5>
<button type="button" class="btn-close close-modal" data-modal-id="pelanggan"></button>
</div>
<div class="modal-body">
<div class="form-check">
<input class="form-check-input" type="radio" name="optionsRadios" id="option1" value="1">
<label class="form-check-label" for="option1">张三科技有限公司</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="optionsRadios" id="option2" value="2">
<label class="form-check-label" for="option2">李四贸易公司</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary close-modal" data-modal-id="pelanggan">取消</button>
<button type="button" class="btn btn-primary confirm-modal" data-modal-id="pelanggan" data-target="#selectedPelanggan">确定</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="vendor" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">选择供应商</h5>
<button type="button" class="btn-close close-modal" data-modal-id="vendor"></button>
</div>
<div class="modal-body">
<div class="form-check">
<input class="form-check-input" type="radio" name="optionsRadios" id="v-option1" value="1">
<label class="form-check-label" for="v-option1">A材料厂</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="optionsRadios" id="v-option2" value="2">
<label class="form-check-label" for="v-option2">B配件公司</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary close-modal" data-modal-id="vendor">取消</button>
<button type="button" class="btn btn-primary confirm-modal" data-modal-id="vendor" data-target="#selectedVendor">确定</button>
</div>
</div>
</div>
</div>
<!-- 目标输入框 -->
<input type="text" id="selectedPelanggan" placeholder="已选客户" readonly>
<input type="text" id="selectedVendor" placeholder="已选供应商" readonly>// ✅ 通用模态框控制函数
function openModal(modalId) {
$(`#${modalId}`).modal('show');
}
function closeModal(modalId) {
$(`#${modalId}`).modal('hide');
}
// ✅ 通用数据回填函数(支持任意目标字段)
function updateTargetValue(modalId, targetSelector) {
const selected = $(`#${modalId} input[name=optionsRadios]:checked`);
if (selected.length) {
const val = selected.val();
// 动态匹配 label:注意 radio 的 for 属性需与选项 ID 一致(如 option1 → for="option1")
const label = $(`#${modalId} label[for=option${val}], #${modalId} label[for=v-option${val}]`).text();
$(targetSelector).val(label).trigger('change'); // 触发 change 便于后续监听
}
}
// ✅ 清理函数:重置所有 radio 并清空状态
function clearModalSelection(modalId) {
$(`#${modalId} input[name=optionsRadios]`).prop('checked', false);
}
// ? 统一事件绑定
$(document).ready(function() {
// 打开模态框
$('.open-modal').on('click', function() {
const modalId = $(this).data('modal-id');
openModal(modalId);
});
// 关闭模态框(含“X”、取消按钮)
$('.close-modal').on('click', function() {
const modalId = $(this).data('modal-id');
closeModal(modalId);
clearModalSelection(modalId); // 确保每次打开都是干净状态
});
// 确认并回填数据
$('.confirm-modal').on('click', function() {
const modalId = $(this).data('modal-id');
const target = $(this).data('target');
updateTargetValue(modalId, target);
closeModal(modalId);
clearModalSelection(modalId);
});
// 【可选】点击遮罩层关闭时也执行清理
$('.modal').on('hidden.bs.modal', function () {
const modalId = $(this).attr('id');
clearModalSelection(modalId);
});
});⚠️ 注意事项与最佳实践
- ID 命名一致性:确保每个模态框 id、触发按钮 data-modal-id、目标输入框 id 及 radio 的 id/for 属性形成可预测映射(如 pelanggan → option1, v-option1),便于动态定位;
- Bootstrap 版本适配:上述代码基于 Bootstrap 5(使用 modal('show') 和 hidden.bs.modal 事件);若使用 Bootstrap 4,请将 btn-close 替换为 <button class="close">×</button>,事件名改为 hidden.bs.modal(相同);
- 避免全局污染:所有函数均封装在 $(document).ready() 内,或建议进一步封装为模块(如 IIFE 或 ES Module);
- 无障碍增强:为 .modal 添加 aria-labelledby 和 role="dialog" 属性,提升可访问性;
- 性能优化:使用事件委托(如 $(document).on('click', '.open-modal', ...))可支持动态生成的按钮。
通过该方案,你只需维护一份核心逻辑,新增模态框仅需复制 HTML 结构并修改 id 和 data-* 属性,彻底告别重复函数,大幅提升代码可维护性与可扩展性。

















