Flask结合Jinja实现Bootstrap Listgroup Scrollspy失效报错排查
故障原因
控制台抛出uncaught TypeError: i is null是Bootstrap Scrollspy初始化匹配锚点失败导致的,核心问题出在id属性的写法错误,另外还有两处影响功能和后续扩展的问题:
- 核心错误:你给滚动区域内的内容卡片设置id时,错误将锚点前缀
#写进了id属性值。#仅作为锚点链接、CSS选择器的定位标记使用,元素自身的id属性不能包含这个符号,导致Scrollspy根据导航a标签的href值查找对应内容节点时,匹配不到目标元素,拿到null值直接触发类型错误。 - 功能bug:课程落地页的a标签闭合位置错误,链接文本写在了标签外部,点击不会跳转。
- 扩展隐患:外层遍历
choices生成多组列表时,所有导航容器都用了固定idlist-example,后续添加多组数据时会出现id重复,导致Scrollspy定位混乱。
你写的Scrollspy相关CSS是符合Bootstrap官方要求的,不需要修改。
修正方案
- 删除内容卡片id属性里多余的前置
# - 利用Jinja模板的
loop.parent属性拼接组索引和项索引,生成全局唯一的导航id、锚点id,提前适配多组数据场景 - 调整a标签闭合位置,把链接文本放到标签内部
修正后的模板代码如下:
{% extends "layout.html" %} {% block title %} Results {% endblock %} {% block main %} <!--course display--> {% for i in choices %} <div class= "container-fluid"> <div class="row justify-content-center"> <div class="col-9 heading"> <div> <h1>Coursera Courses</h1> </div> </div> </div> <div class="row justify-content-center result-background"> <!-- 每组生成独立导航ID,避免多组数据ID冲突 --> <div id="list-example-{{ loop.index }}" class="col-2 list-group"> {% for dict in i%} <a class="list-group-item list-group-item-dark list-group-item-action" href="#list-item-{{ loop.parent.loop.index }}-{{ loop.index }}">{{ dict["Course Name"] }}</a> {% endfor %} </div> <div class="col-7"> <!-- 绑定对应组的导航容器 --> <div class="scrollspy-example" data-bs-spy="scroll" data-bs-target="#list-example-{{ loop.index }}" data-bs-offset="40" tabindex="0"> {% for dict in i %} <!-- 移除ID中多余的#,拼接全局唯一ID --> <div class="boxlayout" id="list-item-{{ loop.parent.loop.index }}-{{ loop.index }}"> <img src="{{ dict["Image URL"] }}" alt="course cover" class="img-thumbnail" align="left" width="15%" height="15%"> <h2>{{ dict["Course Name"] }}</h2> <details close> <summary>课程详情</summary> 待填充课程介绍内容 </details> </br> <table> <tr> <td>出品方</td><td>Coursera</td> </tr> <tr> <td>证书类型</td><td>{{ dict["Certificate"] }}</td> </tr> <tr> <td>当前价格</td><td>${{ dict["Current Price"] }}</td> </tr> <tr> <!-- 修正a标签结构 --> <td><a href="{{ dict["URL"] }}">课程落地页</a></td> </tr> </table> </div> {% endfor %} </div> </div> </div> </div> {% endfor %} {% endblock %}
修改完成后清空浏览器缓存刷新页面,Scrollspy的滚动联动、导航高亮功能就可以正常运行,控制台不会再抛出空对象错误,后续添加多组课程列表数据时也不会出现id冲突问题。
内容的提问来源于stack exchange,提问作者simonrbk
相关产品推荐
相关产品推荐

