Bootstrap 4 Popover无法通过AJAX加载动态生成代码求助
Fix Bootstrap 4 Popover Dynamic AJAX Content Loading Issue
我完全懂你卡在哪了——AJAX的异步特性在这儿给你挖了个坑!你的代码里content函数会在AJAX请求完成前就返回加载spinner,等请求拿到真实数据时,popover早就渲染完了,根本不会再更新内容。至于直接在success里返回数据报错,是因为Bootstrap的popover组件期望content立即返回可渲染的内容,异步回调里的返回值它根本捕获不到,自然会触发 sanitizer 的未定义错误。
问题根源拆解
- AJAX默认是异步执行的,
return fetch_data会先跑,此时fetch_data还是初始的spinner HTML。等AJAX成功后修改fetch_data,popover已经完成渲染,这个变量的变化完全没用。 - 直接在success里返回
data无效,因为这个返回值不会被popover的content函数接收,反而会让Bootstrap的内容处理逻辑拿到一个未定义值,抛出Cannot read property 'length' of undefined错误。
推荐解决方案:异步加载+动态更新Popover内容
正确的思路是先给用户显示加载状态,等popover完全显示后再发起AJAX请求,拿到数据后替换掉加载内容。我们可以利用Bootstrap的shown.bs.popover事件来实现这个流程:
$('.popu').popover({ html: true, placement: 'auto', trigger: 'hover', content: function(){ // 先返回加载中的spinner,给用户即时反馈 return '<div class="d-flex justify-content-center"><div class="spinner-border" role="status"><span class="sr-only">Lade...</span></div></div>'; } }) // 当popover完全显示后触发AJAX请求 .on('shown.bs.popover', function() { var $currentElement = $(this); var popoverInstance = $currentElement.data('bs.popover'); var itemId = $currentElement.attr("id"); $.ajax({ url: `ajax/SucheBedarfspositionenAuslesen.php?nr=${itemId}`, success: function(data) { // 替换popover的内容容器为返回的HTML $(popoverInstance.$tip).find('.popover-body').html(data); }, error: function() { // 请求失败时显示友好提示 $(popoverInstance.$tip).find('.popover-body').html('<div class="text-danger">无法加载内容,请稍后重试</div>'); } }); }) // 可选:隐藏popover时重置内容,确保下次hover重新加载 .on('hide.bs.popover', function() { var popoverInstance = $(this).data('bs.popover'); $(popoverInstance.$tip).find('.popover-body').html('<div class="d-flex justify-content-center"><div class="spinner-border" role="status"><span class="sr-only">Lade...</span></div></div>'); });
代码说明
- 初始化popover时,
content直接返回加载spinner,保证用户hover时立刻有视觉反馈。 - 绑定
shown.bs.popover事件:popover完全显示后,发起AJAX请求获取真实内容,再替换掉加载状态。 - 绑定
hide.bs.popover事件(可选):隐藏popover时重置内容,避免下次hover直接显示旧数据。
额外建议:修复PHP的SQL注入风险
你的PHP代码虽然用了filter_input,但直接拼接SQL语句还是有注入风险,推荐改用预处理语句彻底解决:
<?php include("../config.inc.php"); ?> <table class="table"> <thead class="bg-info"> <tr> <th scope="col">Bestellung</th> <th scope="col">Bezeichnung</th> <th scope="col" class="text-center">Anzahl</th> <th scope="col">Lieferant</th> </tr> </thead> <tbody> <?php $Bedarfsnummer = filter_input(INPUT_GET, "nr", FILTER_SANITIZE_NUMBER_INT); // 使用预处理语句避免SQL注入 $stmt = $mysqli->prepare("SELECT id, Bedarfsnummer, Bestellung, Bezeichnung, Anzahl, Lieferant, REQ, RITM, Notiz FROM bedarfspositionen WHERE Bedarfsnummer = ?"); $stmt->bind_param("i", $Bedarfsnummer); // 假设Bedarfsnummer是整数类型 $stmt->execute(); $result = $stmt->get_result(); while($Bedarfsposition = $result->fetch_assoc()) { ?> <tr> <th scope="row"><?php echo $Bedarfsposition['Bestellung'];?></th> <td><?php echo $Bedarfsposition['Bezeichnung'];?></td> <td class="text-center"><?php echo $Bedarfsposition['Anzahl'];?></td> <td><?php echo $Bedarfsposition['Lieferant'];?></td> </tr> <?php } $stmt->close(); ?> </tbody> </table>
这样修改后,既解决了popover的动态加载问题,又加固了后端的安全性,测试一下应该就能正常显示表格内容了!
内容的提问来源于stack exchange,提问作者Johnnii360
相关产品推荐
相关产品推荐

