基于jQuery 3.6.1和Bootstrap 5.2.3的可复用下拉菜单报错求助
问题
使用jQuery 3.6.1和Bootstrap 5.2.3构建可复用下拉菜单,需求是通过点击按钮的data属性动态更新下拉菜单链接。参考原生JS方案改用jQuery实现后,点击操作按钮“...”时出现如下错误:
{ "message": "Uncaught TypeError: Cannot read properties of null (reading 'classList')", "filename": "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/js/bootstrap.bundle.min.js", "lineno": 6, "colno": 44054 }
原代码如下:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js" integrity="sha512-aVKKRRi/Q/YV+4mjoKBsE4x3H+BkegoM/em46NNlCqNTmUYADjBbeNefNxYV7giUp0VxICtqdrbqU7iVaeZNXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css" integrity="sha512-SbiR/eusphKoMVVXysTKG/7VseWii+Y3FdHrt0EpKgpToZeemhqHeZeLWLhJutz/2ut2Vw1uQEj2MbRF+TVBUA==" crossorigin="anonymous" referrerpolicy="no-referrer" /> </head> <body> <table class="table"> <thead> <tr> <th>Type</th> <th>Action</th> </tr> </thead> <tbody> <tr> <td>item 1</td> <td> <div class="dropdown"> <button type="button" class="btn btn-primary" data-type="ddbtn" data-id="1" data-value="some value 1" data-bs-toggle="dropdown" aria-expanded="false" >...</button> </div> </td> </tr> <tr> <td>item 2</td> <td> <div class="dropdown"> <button type="button" class="btn btn-primary" data-type="ddbtn" data-id="2" data-value="some value 2" data-bs-toggle="dropdown" aria-expanded="false" >...</button> </div> </td> </tr> </tbody> </table> <ul id="contextMenu" class="dropdown-menu"> <li><a href="#" tabindex="-1" class="dropdown-item" id="link1">Action 1</a></li> <li><a href="#" tabindex="-1" class="dropdown-item" id="link2">Action 2</a></li> </ul> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/js/bootstrap.bundle.min.js" integrity="sha512-i9cEfJwUwViEPFKdC1enz4ZRGBj8YQo6QByFTF92YXHi7waCqyexvRD75S5NVTsSiTv7rKWqG9Y5eFxmRsOn0A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script> $(function () { $dropdown = $("#contextMenu"); // let's get the dropdown menu $("button[data-type='ddbtn']").click(function () { var id = $(this).data("id"); console.log(id); $("#link1").attr("href","/action/dosomething?id=" + id); $("#link1").text($(this).data("value")); // just for test purposes. $("#link2").attr("href","/action/somethingelse?id=" + id); $(this).dropdown(); }); }); </script> </body> </html>
解决方案
错误原因是Bootstrap 5的下拉组件默认会在触发按钮的父容器(.dropdown)内寻找下拉菜单,但你的#contextMenu独立于按钮容器之外,导致组件找不到菜单元素,抛出null错误。
修复步骤:
- 给触发按钮添加
data-bs-target="#contextMenu"属性,明确指定下拉菜单的目标元素 - 移除手动调用的
$(this).dropdown(),data-bs-toggle="dropdown"已经自动绑定了触发逻辑 - 可选:为避免多个按钮触发同一菜单时的状态混乱,更新菜单前可先关闭其他打开的下拉菜单
修正后的完整代码:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js" integrity="sha512-aVKKRRi/Q/YV+4mjoKBsE4x3H+BkegoM/em46NNlCqNTmUYADjBbeNefNxYV7giUp0VxICtqdrbqU7iVaeZNXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css" integrity="sha512-SbiR/eusphKoMVVXysTKG/7VseWii+Y3FdHrt0EpKgpToZeemhqHeZeLWLhJutz/2ut2Vw1uQEj2MbRF+TVBUA==" crossorigin="anonymous" referrerpolicy="no-referrer" /> </head> <body> <table class="table"> <thead> <tr> <th>Type</th> <th>Action</th> </tr> </thead> <tbody> <tr> <td>item 1</td> <td> <div class="dropdown"> <button type="button" class="btn btn-primary" data-type="ddbtn" data-id="1" data-value="some value 1" data-bs-toggle="dropdown" data-bs-target="#contextMenu" aria-expanded="false">...</button> </div> </td> </tr> <tr> <td>item 2</td> <td> <div class="dropdown"> <button type="button" class="btn btn-primary" data-type="ddbtn" data-id="2" data-value="some value 2" data-bs-toggle="dropdown" data-bs-target="#contextMenu" aria-expanded="false">...</button> </div> </td> </tr> </tbody> </table> <ul id="contextMenu" class="dropdown-menu"> <li><a href="#" tabindex="-1" class="dropdown-item" id="link1">Action 1</a></li> <li><a href="#" tabindex="-1" class="dropdown-item" id="link2">Action 2</a></li> </ul> <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/js/bootstrap.bundle.min.js" integrity="sha512-i9cEfJwUwViEPFKdC1enz4ZRGBj8YQo6QByFTF92YXHi7waCqyexvRD75S5NVTsSiTv7rKWqG9Y5eFxmRsOn0A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script> $(function () { const $dropdown = $("#contextMenu"); $("button[data-type='ddbtn']").on("click", function () { const id = $(this).data("id"); const value = $(this).data("value"); // 更新菜单链接和文本 $("#link1").attr("href", `/action/dosomething?id=${id}`).text(value); $("#link2").attr("href", `/action/somethingelse?id=${id}`); }); }); </script> </body> </html>
额外说明:
- Bootstrap 5的下拉组件通过
data-bs-target指定菜单元素,当菜单不在触发按钮父容器内时必须显式设置 - 手动调用
.dropdown()会重复初始化组件导致冲突,依赖data-bs-toggle即可自动处理触发逻辑 - 使用模板字符串(
${id})可让URL拼接更清晰,若需兼容旧环境可继续用字符串拼接
内容的提问来源于stack exchange,提问作者Sha
相关产品推荐
相关产品推荐

