Bootstrap 5 Popover异步函数动态设置内容不显示问题
Bootstrap 5 Popover异步加载内容不显示的解决方案
你的问题出在Bootstrap 5的Popovercontent回调不支持直接返回Promise——当前代码里,content函数内部的立即执行async函数返回的是Promise对象,而非实际的HTML字符串,导致Popover无法正确渲染内容。
问题代码分析
原初始化代码中,content回调返回未处理的Promise,无法被Popover识别:
document.querySelectorAll('[data-bs-toggle="popover"]').forEach(function (popover) { new bootstrap.Popover(popover, { content: function () { // 返回的是Promise,不是字符串内容 (async () => { var x = await SetPopoverContent(); return x; })() } }); });
修复方案
通过监听Popover的show.bs.popover事件,在弹窗显示前异步加载内容并手动更新弹窗DOM:
- 先初始化Popover,设置默认加载占位内容
- 监听显示事件,异步获取内容后更新弹窗
// 初始化所有Popover document.querySelectorAll('[data-bs-toggle="popover"]').forEach(function (popoverEl) { // 初始化时设置加载中内容 const popover = new bootstrap.Popover(popoverEl, { content: '<p>加载中...</p>' }); // 监听弹窗显示前的事件 popoverEl.addEventListener('show.bs.popover', async function () { // 异步获取内容 const content = await SetPopoverContent(); // 更新Popover的配置内容 popover._config.content = content; // 手动更新弹窗DOM(如果弹窗实例已创建) if (popover.tip) { popover.tip.querySelector('.popover-body').innerHTML = content; } }); });
调整后的SetPopoverContent函数
确保参数可正确获取(比如从触发元素的dataset属性读取messageId):
async function SetPopoverContent() { let contentText = ''; // 建议从触发元素的dataset获取messageId,避免作用域问题 // const messageId = popoverEl.dataset.messageId; let data = await dotNetReference.invokeMethodAsync('GetChatToInfo', messageId); if (data != null && data != undefined) { const outerDiv = document.createElement('div'); // 这里添加你的DOM构建逻辑,例如: // outerDiv.innerHTML = `<div>用户:${data.name}<br>详情:${data.detail}</div>`; contentText = outerDiv.innerHTML; } else { contentText = '<p>加载失败</p>'; } return contentText; }
关键说明
- Bootstrap 5的
content回调仅支持同步返回字符串/元素,不处理Promise对象 show.bs.popover事件在弹窗显示前触发,此时异步获取内容后更新DOM,能保证弹窗显示正确内容- 若需要每次触发弹窗都重新加载内容,可改用
shown.bs.popover事件,但注意避免重复发起请求
内容的提问来源于stack exchange,提问作者GH DevOps
相关产品推荐
相关产品推荐

