模态窗口中Leader Line.js元素连线功能失效问题求助
问题
需要将<table>加载到Bootstrap模态窗口中,同时使用Leader Line构造函数绘制连线连接元素。当<table>直接放在index.php页面时连线正常显示,但放入模态窗口后功能失效。
场景效果:
<table>在index.php页面时:连线正常渲染<table>在未打开的模态窗口中时:连线无法正确生成<table>在已打开的模态窗口中时:连线位置错乱或完全不显示
代码示例
index.php
<body translate="no"> <div class="container" style="width: 800px"> <div class="modal-control my-3"> <p> <a href="#" class="btn btn-primary mb-3" data-bs-toggle="modal" data-bs-target="#ChartFlowModal"> open Chart </a> </p> </div> <?php include('charts-modal.php');?> </div> <!-- Initialize jQuery Library --> <script src="jQuery/jquery-3.7.1/jquery.js" type="text/javascript"></script> <!-- Bootstrap Library --> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.bundle.min.js" type="text/javascript"></script> <!-- Leader Line Library --> <script src="https://cdnjs.cloudflare.com/ajax/libs/leader-line/1.0.7/leader-line.min.js" type="text/javascript"></script> <!-- Leader Line custom settings --> <script> // Draw a line between two elements function drawLine(e1, e2) { var line = new LeaderLine( e1, e2, ); line.setOptions({startSocket: 'right', endSocket: 'bottom'}); line.color = '#999'; line.startPlug = 'behind'; line.endPlug = 'behind'; line.path = 'grid'; line.size = 1; } drawLine ( document.getElementById('role-text-1.1'), document.getElementById('role-text-1.2') ); drawLine ( document.getElementById('role-text-2.1'), document.getElementById('role-text-2.2') ); </script> </body>
charts-modal.php
<!-- Modal --> <div class="modal fade" id="ChartFlowModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true"> <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="staticBackdropLabel">Modal title</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <table class="sku-table" style="width: 100%; border: thin solid white;"> <tr> <th style="width: 20%; text-align: center;">Contain</th> <th style="width: 10%; text-align: center;">Type</th> <th style="width: 10%; text-align: center;">Subcategory</th> </tr> <tr style="height: 5px;"> <td colspan='3'></td> </tr> <tr class="end-values"> <td></td> <td id="role-text-1.2" style="text-align: center;">4</td> <td id="role-text-2.2" style="text-align: center;">01</td> </tr> <tr> <td colspan="3"> <ul class="sku-structure"> <li class="bi bi-circle-fill"><strong>Type</strong><span class="source-values">Processors</span> <ul> <li class="bi-square"><a>Type name</a><span class="to-card">Processors</span></li> <li class="bi-1-square-fill"><a>Type code</a><span class="to-sku">4</span><span id="role-text-1.1"></span></li> </ul> </li> <li class="bi bi-circle-fill pt-2"><strong>Subcategory</strong><span class="source-values">GPU line</span> <ul> <li class="bi-square"><a>Subcategory name</a><span class="to-card">GPU line</span></li> <li class="bi-2-square-fill"><a>Subcategory code</a><span class="to-sku">01</span><span id="role-text-2.1"></span></li> </ul> </li> </ul> </td> </tr> </table> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Understood</button> </div> </div> </div> </div>
解决方案
核心原因
- 模态窗口初始状态为隐藏(
display: none),页面加载时Leader Line尝试获取隐藏元素的位置信息,此时元素的尺寸和坐标均为0,导致连线绘制失败。 - 当前代码在页面加载完成后立即调用
drawLine,但此时模态窗口未显示,目标元素的布局信息无法被正确读取。
修复步骤
- 监听模态窗口显示事件:在模态窗口完全显示(
shown.bs.modal事件触发)后再绘制连线,此时元素的位置和尺寸已可正常获取。 - 清理旧连线:避免重复打开模态时生成多条重复连线,每次打开前清除已存在的Leader Line实例。
修改后的脚本代码
<script> // 存储Leader Line实例,用于后续清理 let leaderLines = []; // Draw a line between two elements function drawLine(e1, e2) { var line = new LeaderLine( e1, e2, ); line.setOptions({startSocket: 'right', endSocket: 'bottom'}); line.color = '#999'; line.startPlug = 'behind'; line.endPlug = 'behind'; line.path = 'grid'; line.size = 1; leaderLines.push(line); return line; } // 监听模态窗口完全显示事件 $('#ChartFlowModal').on('shown.bs.modal', function () { // 清理之前的连线实例 leaderLines.forEach(line => line.remove()); leaderLines = []; // 绘制新连线 drawLine ( document.getElementById('role-text-1.1'), document.getElementById('role-text-1.2') ); drawLine ( document.getElementById('role-text-2.1'), document.getElementById('role-text-2.2') ); }); // 监听模态隐藏事件,清理连线释放资源 $('#ChartFlowModal').on('hidden.bs.modal', function () { leaderLines.forEach(line => line.remove()); leaderLines = []; }); </script>
额外优化建议
- 确保模态窗口内的元素仅使用Bootstrap默认的隐藏方式,不要额外设置
visibility: hidden或opacity: 0,否则Leader Line仍无法读取正确布局信息。 - 如果模态窗口存在动态内容加载,需在内容加载完成后再触发连线绘制逻辑。
内容的提问来源于stack exchange,提问作者Gediminas
相关产品推荐
相关产品推荐

