Bootstrap 5:从Modal打开的Popover表单输入框无法输入
解决Bootstrap Modal内Popover输入框无法聚焦的问题
问题场景
在Bootstrap Modal中打开Popover时,Popover内的输入框完全无法输入内容,焦点一直被锁在Modal里的readonly输入框上,调整Popover的HTML代码位置也没效果。
问题根源
- Bootstrap Modal的焦点陷阱机制:Modal会强制把焦点限制在自身内部的可聚焦元素中,防止焦点跑到Modal外部,这是无障碍设计的要求,但会导致外部Popover的输入框无法获取焦点。
- readonly输入框仍可聚焦:Modal里的readonly输入框虽然不能编辑,但默认还是属于可聚焦元素,Modal的焦点陷阱会不断将焦点拉回这个输入框。
- Popover输入框的tabindex设置错误:Popover内的输入框加了
tabindex="-1",这个属性会让元素无法被聚焦,直接导致点击输入框也拿不到焦点。
解决方案
1. 修正Popover输入框的tabindex
删掉Popover输入框的tabindex="-1",让它恢复可聚焦性:
<input type="tel" name="new-recipient-tel-input" id="new-recipient-tel-input" class="form-control" aria-label="Phone number input" placeholder="Phone number..." />
2. 让readonly输入框失去可聚焦性
给Modal里的readonly输入框加上tabindex="-1",这样Modal的焦点陷阱就不会再盯上它:
<input type="text" class="form-control" id="recipient-tel" value="+44741100000" readonly tabindex="-1" />
3. 将Popover挂载到Modal内部
默认Popover会被挂载到<body>下,属于Modal外部元素。通过container选项把Popover挂载到Modal内部,让Modal的焦点陷阱能识别它:
var popover = new bootstrap.Popover(exampleEl, { html: true, sanitize: false, title: "Input New Telephone Number", content: $('[data-name="popover-content"]'), container: '#testScreen' // 指定Modal作为挂载容器 });
4. 手动控制焦点(可选增强)
监听Popover的显示事件,在它弹出后自动把焦点设置到内部输入框:
exampleEl.addEventListener('shown.bs.popover', function () { document.getElementById('new-recipient-tel-input').focus(); });
修改后的完整代码
HTML
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="modal fade" id="testScreen" tabindex="-1" aria-labelledby="testScreenLabel" aria-hidden="true" data-bs-theme="dark" data-bs-backdrop="static" data-bs-keyboard="false"> <div class="modal-dialog modal-fullscreen modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" id="testScreenLabel">Modal Title</h1> </div> <div class="modal-body"> <div class="mb-3"> <label class="form-label">Tel:</label> <form class="row"> <div class="col-sm-7 input-group-sm"> <input type="text" class="form-control" id="recipient-tel" value="+44741100000" readonly tabindex="-1" /> </div> <div class="col-sm-5"> <a tabindex="0" id="locate-change-recipient-btn" class="btn btn-sm btn-warning" role="button">Change Recipient</a> <div style="display:none;"> <div data-name="popover-content"> <div class="col-sm-12 input-group-sm"> <input type="tel" name="new-recipient-tel-input" id="new-recipient-tel-input" class="form-control" aria-label="Phone number input" placeholder="Phone number..." /> </div> <button class="btn btn-sm btn-success" id="locate-new-receipient-tel-btn">Confirm</button> </div> </div> </div> </form> </div> </div> </div> </div> </div>
JavaScript
// 初始化Popover var exampleEl = document.getElementById('locate-change-recipient-btn') var popover = new bootstrap.Popover(exampleEl, { html: true, sanitize: false, title: "Input New Telephone Number", content: $('[data-name="popover-content"]'), container: '#testScreen' }); // Popover显示后自动聚焦输入框 exampleEl.addEventListener('shown.bs.popover', function () { document.getElementById('new-recipient-tel-input').focus(); }); // 打开Modal var testScreen = new bootstrap.Modal(document.getElementById('testScreen')); testScreen.show();
内容的提问来源于stack exchange,提问作者TangoMike
相关产品推荐
相关产品推荐

