Bootstrap 官方不提供穿梭框组件,需用 list-group、btn-group 等基础样式手写两个并排列表及中间按钮,并通过 JavaScript 维护数据状态或搬运 DOM 节点实现选项移动,同时注意无障碍、响应式、表单回显等细节。

Bootstrap 本身不提供穿梭框(Transfer)组件,bootstrap 的官方 JS 插件和 CSS 类里没有 transfer、move-between-lists 或类似语义的实现。你得自己组合基础元素 + 逻辑,或者引入第三方库补充。
用 Bootstrap 基础样式手写穿梭框结构
核心是两个并排的 <ul></ul> 或 <div class="list-group">,加上中间的控制按钮。Bootstrap 的 <code>list-group、btn-group 和 form-check 足够支撑 UI 层。
- 左侧列表用
<ul class="list-group"></ul>,每项带form-check复选框,方便批量操作 - 右侧同理,但初始为空
- 中间按钮组推荐用
<div class="btn-group-vertical"> 垂直堆叠 <code><button type="button" class="btn btn-sm"></button> - 别忘了加
aria-label和tabindex,否则键盘用户无法操作 - 推荐用「数据驱动」:维护一个数组状态(如
leftItems/rightItems),每次点击按钮就更新数组,再调用函数重新生成两个列表的 HTML - 如果坚持 DOM 搬运,记得把复选框的
checked状态同步过去,否则移过去还是未选中 -
event.preventDefault()必须加在按钮点击上,避免表单意外提交 - 批量移动时,遍历要从后往前删(
for (let i = els.length - 1; i >= 0; i--)),否则索引会错乱 - Bootstrap 5 的
col-md-5左右各占,中间按钮用col-md-2;小屏幕建议改成垂直流式布局(flex-column) - 搜索框建议加在左侧列表上方,用
input-group包裹,但注意input-group在list-group内部需要额外mb-2 - 没选项时,
<small class="text-muted">暂无数据</small>比留白更友好 - 移动端慎用拖拽:iOS Safari 对
dragstart支持不稳定,优先用点击+长按模拟
用 JavaScript 控制选项移动(关键逻辑)
移动不是靠 CSS 动画,而是 DOM 节点搬运或数据驱动重渲染。最直接的方式是操作 element.appendChild(),但要注意:原生节点移走后,事件监听器会丢失。
兼容性与交互细节容易被忽略
穿梭框看似简单,但真实业务中常卡在几个地方:搜索过滤、拖拽支持、空状态提示、响应式断点下的布局折叠。
真正难的不是画两个框,而是让「已选中项」的状态在页面刷新、表单提交、校验失败回显时不丢失——这意味着你得把右侧列表的数据映射成表单字段(比如多个 <input type="hidden" name="selected_ids" value="123">),而不是只存在 JS 变量里。


















