滚动页面高亮导航链接报错:Uncaught TypeError 求助
问题分析与解决方案
错误根源
报错Uncaught TypeError: Cannot read properties of undefined (reading 'add')的核心原因是你在循环中直接对字符串调用classList.add()方法:
sectionIdTonavigationLink[id] = '#navigation > ul > li > a [href=\#' + id + ']'.classList.add('active') ;
字符串本身没有classList属性,因此触发了这个错误。而且这段代码逻辑完全多余,后续的highlightNavigation函数已经负责导航高亮处理。
完整修正步骤
1. 删除无效循环代码
直接移除这段报错且无意义的循环:
var sectionIdTonavigationLink = {}; for (var i = sections.length -1; i >= 0; i--) { var id = sections[i].id; sectionIdTonavigationLink[id] = '#navigation > ul > li > a [href=\#' + id + ']'.classList.add('active') ; }
2. 修复滚动判断逻辑
原逻辑scrollPosition >= sectionTop会让所有顶部在滚动位置之上的section都触发高亮,最终只有最后一个生效。需要加上section高度判断,确保当前滚动位置处于section范围内:
function highlightNavigation() { var scrollPosition = window.pageYOffset; // 获取窗口高度,用于判断section是否在视口中 var windowHeight = window.innerHeight; sections.forEach(function(item) { var sectionTop = item.offsetTop; var sectionHeight = item.offsetHeight; // 滚动位置处于当前section范围内(预留10px偏移量,提升体验) if (scrollPosition >= sectionTop - 10 && scrollPosition < sectionTop + sectionHeight - 10) { var id = item.getAttribute('id'); // 移除所有导航的active类,再给对应导航添加 $('#navigation ul li a').removeClass('active'); $('#navigation ul li a[href="#' + id + '"]').addClass('active'); } }); }
3. 绑定滚动与初始化事件
添加事件监听,让函数在页面加载和滚动时触发:
// 页面加载完成后初始化一次,确保初始状态正确 window.addEventListener('load', highlightNavigation); // 绑定滚动事件,实时更新导航状态 window.addEventListener('scroll', highlightNavigation);
4. 修正选择器空格问题
原选择器#navigation > ul > li > a [href=\#' + id + ']中的空格会导致错误匹配(会查找a标签的子元素而非a本身),去掉空格后改为a[href="#id"],才能正确匹配对应href属性的a标签。
完整修正代码
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <title>Hello, world!</title> <style> #navigation { position: fixed; } #sections { position: absolute; left: 150px; } .section { height: 200px; margin: 10px; padding: 10px; border: 1px dashed black; } #section5 { height: 1000px; } .active { background: red; } </style> </head> <body> <div id="navigation"> <ul> <li><a href="#section1">Section 1</a></li> <li><a href="#section2">Section 2</a></li> <li><a href="#section3">Section 3</a></li> <li><a href="#section4">Section 4</a></li> <li><a href="#section5">Section 5</a></li> </ul> </div> <div id="sections"> <section id="section1" class="section"> I'm section 1 </section> <section id="section2" class="section"> I'm section 2 </section> <section id="section3" class="section"> I'm section 3 </section> <section id="section4" class="section"> I'm section 4 </section> <section id="section5" class="section"> I'm section 5 </section> </div> <script> var navigationLink = document.querySelectorAll('#navigation > ul > li > a'); let sections = document.querySelectorAll('.section[id]'); function highlightNavigation() { var scrollPosition = window.pageYOffset; var windowHeight = window.innerHeight; sections.forEach(function(item) { var sectionTop = item.offsetTop; var sectionHeight = item.offsetHeight; if (scrollPosition >= sectionTop - 10 && scrollPosition < sectionTop + sectionHeight - 10) { var id = item.getAttribute('id'); $('#navigation ul li a').removeClass('active'); $('#navigation ul li a[href="#' + id + '"]').addClass('active'); } }); } // 初始化与绑定事件 window.addEventListener('load', highlightNavigation); window.addEventListener('scroll', highlightNavigation); </script> </body> </html>
内容的提问来源于stack exchange,提问作者willy
相关产品推荐
相关产品推荐

