Bootstrap Collapse加入PHP代码后无法显示全部折叠面板如何解决?
Bootstrap Collapse折叠面板展开异常问题修复
场景说明
在PHP项目中使用Bootstrap 4的Collapse折叠组件实现三个互斥的折叠面板,按钮触发代码如下:
<div class="text-center" id="bott"> <p> <button class="bottone-isbn btn-lg btn-info" type="button" data-toggle="collapse" data-target="#demo1" aria-expanded="false" aria-controls="demo1"> ISBN </button> <button class="bottone-key btn-lg btn-info" type="button" data-toggle="collapse" data-target="#demo2" aria-expanded="false" aria-controls="demo2"> Parola chiave (titolo, autore) </button> <button class="bottone-manuale btn-lg btn-info" type="button" data-toggle="collapse" data-target="#demo3" aria-expanded="false" aria-controls="demo3"> Manualmente </button> </p> </div>
三个折叠面板demo1、demo2结构相似,内部嵌入PHP代码动态渲染查询到的图书数据,demo1代码示例如下:
<div class="collapse" id="demo1"> <br> <br> <div class="card card-body"> <ul> <h1><li>ISBN: </li></h1> <br> <br> <div class="container" id="cerca"> <div class="search-container"> <form action="aggiungiLibro.php" method="GET" name="search-form"> <input id="search-input" size="40" type="text" placeholder=" Inserisci ISBN..." name="isbn"> <button name="invio" id="search-button" type="submit"><i class="fas fa-check" style="color:white;"></i></button> </form> </div> </div> <h1 class="text-center">Libri trovati:</h1> <br> <?php if (isset($_GET["invio"])) { $isbn=$_GET["isbn"]; $query="SELECT * FROM libri_DB WHERE libri_DB.isbn = '$isbn'"; } $result=mysqli_query($db, $query); $result_check=mysqli_num_rows($result); if ($result_check > 0) { for ($i=1; $i <= $result_check; $i++) { $row=mysqli_fetch_assoc($result); $libro=$row["nome"]; //layout ricerca $risultato=' <div class="container"> <!--container singolo libro --> <!-- riga 1 --> <div class="row mb-5 mb-lg-0 mt-5" id="libro"> <!-- tabella di una sola riga e due colonne --> <div class="column"> <!-- colonna con immagine --> <img class="card-img" src="img/libri/'.$row["immagine_libro"].'" alt=""/> </div> <div class="column"> <!-- colonna con info --> <div class="card-body"> <h2 class="card-title text-white ml-4 mt-3 mb-3">'.$row["nome"].'</h2> </div> <div class="card-body" id="descrizione"> <!-- lista caratteristiche --> <ul id="dati-libro"> <li class="card-text text-white"><u>Autore:</u> '.$row["autore"].'</li> <li class="card-text text-white"><u>Anno pubblicazione:</u> '.$row["data_pubblicazione"].'</li> <li class="card-text text-white"><u>Casa editrice:</u> '.$row["editore"].'</li> <li class="card-text text-white"><u>Numero di pagine:</u> '.$row["pagine"].'</li> <li class="card-text text-white"><u>ISBN:</u> '.$row["isbn"].'</li> </ul> </div> </div> </div> </div>'; print $risultato; } } ?> </ul> </div> </div>
页面头部引入的资源与自定义互斥JS如下:
<head> <!-- Bootstrap CSS --> <link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <!-- JQuery --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <!-- Bootstrap JS --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> <!-- my CSS --> <link href="css/aggiungiLibro.css" rel="stylesheet"> <script type="text/javascript" src="js/aggiungiLibro.js"></script> <!--funzione per chiudere collapse button attuale quando ne apro uno diverso --> <script> $(document).on('click','#bott',function(){ $('.collapse').collapse('hide'); }) </script> </head>
问题现象
- 多数场景下仅第一个折叠面板可正常展开,其余两个面板点击触发无响应
- 小概率所有面板可正常使用,现象随机出现
- 删除面板内部PHP动态渲染代码后,折叠功能完全正常,加入PHP代码后问题复现
- 移除自定义互斥JS后,面板无自动关闭效果,但仍存在展开异常问题
根因分析
- 自定义互斥JS逻辑冲突:原有JS绑定了按钮容器
#bott的点击事件,点击按钮时会先执行所有面板隐藏逻辑,和Bootstrap原生的折叠展开逻辑是异步执行的,PHP渲染的DOM内容越多,加载耗时越长,两个逻辑的执行时序越不稳定,容易出现刚触发展开的面板又被自定义JS隐藏的问题 - ID重复冲突:demo1中的
cerca、libro、descrizione、dati-libro等ID在demo2、demo3中重复使用,会导致DOM选择器异常,Bootstrap的折叠事件绑定出错 - PHP异常输出破坏DOM结构:当
$_GET["invio"]未触发时,$query变量未定义,会抛出PHP警告,警告内容混入HTML会破坏折叠面板的DOM结构,导致功能失效
修复步骤
1. 替换自定义互斥JS
使用Bootstrap原生的折叠事件实现互斥逻辑,完全避免和原生功能的时序冲突,替换原有自定义JS:
$(document).on('show.bs.collapse', '.collapse', function () { // 仅关闭当前即将展开的面板之外的其他折叠面板 $('.collapse').not(this).collapse('hide'); });
2. 统一修改重复ID
保证所有面板内的元素ID全局唯一,比如demo1的cerca改为cerca-1,demo2对应改为cerca-2,其他重复ID同理按面板区分。
3. 修复PHP代码异常
给$query变量增加默认值,避免未定义报错,同时增加SQL注入防护:
<?php // 初始化默认查询语句,避免变量未定义报错 $query = "SELECT * FROM libri_DB WHERE 1=2"; if (isset($_GET["invio"])) { // 转义用户输入,避免SQL注入风险 $isbn = mysqli_real_escape_string($db, $_GET["isbn"]); $query = "SELECT * FROM libri_DB WHERE libri_DB.isbn = '$isbn'"; } $result=mysqli_query($db, $query); // 后续原有逻辑保持不变 ?>
4. 调整JS加载位置(可选优化)
将所有自定义JS代码移到</body>标签之前加载,确保DOM完全渲染完成后再绑定事件,进一步降低绑定失效概率。
内容的提问来源于stack exchange,提问作者user25896
相关产品推荐
相关产品推荐

