JavaScript遍历div内a元素时href值全部被替换为最后一项的问题
问题原因
你遇到的是JavaScript闭包变量捕获的经典问题:循环里的item没有用let或const声明,它会变成函数作用域的全局变量。当循环结束后,所有点击事件触发时,引用的都是这个变量最终的取值——也就是最后一个<a>的href。
解决方案
方案1:给item添加let声明
把item = nav_item[i]...改成let item = nav_item[i]...,这样每次循环都会创建一个独立的item变量,每个点击事件会捕获对应循环次的变量值:
function NavClick() { var nav_item = document.getElementById('nav-menu').querySelectorAll('div') for (let i = 0; i < nav_item.length; i++) { // 添加let,让item成为每次循环的局部变量 let item = nav_item[i].querySelector('a').getAttribute('href') nav_item[i].addEventListener('click', function(e) { e.preventDefault(); $.ajax({ url: item, contentType: 'application/json', dataType: 'json', success: function(data) { $('title').html(data.title) window.history.replaceState({}, '', item) $('#content').html(data.data) } }); }); } }
方案2:点击时直接从当前元素获取href
不需要提前存item,点击事件触发时,从触发事件的元素里直接找到<a>并获取href,彻底避免闭包问题:
function NavClick() { var nav_item = document.getElementById('nav-menu').querySelectorAll('div') for (let i = 0; i < nav_item.length; i++) { nav_item[i].addEventListener('click', function(e) { e.preventDefault(); // 点击时才获取当前元素下的a标签href const item = this.querySelector('a').getAttribute('href') $.ajax({ url: item, contentType: 'application/json', dataType: 'json', success: function(data) { $('title').html(data.title) window.history.replaceState({}, '', item) $('#content').html(data.data) } }); }); } }
方案3:用forEach简化遍历
用forEach代替for循环,天然避免闭包变量问题,代码更简洁:
function NavClick() { document.getElementById('nav-menu').querySelectorAll('div').forEach(navItem => { navItem.addEventListener('click', function(e) { e.preventDefault(); const item = this.querySelector('a').getAttribute('href') $.ajax({ url: item, contentType: 'application/json', dataType: 'json', success: function(data) { $('title').html(data.title) window.history.replaceState({}, '', item) $('#content').html(data.data) } }); }); }); }
方案4:利用jQuery的事件委托(更高效)
既然已经在用jQuery,直接用事件委托绑定到父元素#nav-menu,不需要遍历每个子元素,性能更好:
function NavClick() { $('#nav-menu').on('click', 'div', function(e) { e.preventDefault(); const item = $(this).find('a').attr('href'); $.ajax({ url: item, contentType: 'application/json', dataType: 'json', success: function(data) { $('title').text(data.title) window.history.replaceState({}, '', item) $('#content').html(data.data) } }); }); }
另外注意你的HTML里第二个<a>的href有语法错误:/myurl/' %},建议修正为/myurl/。
内容的提问来源于stack exchange,提问作者Nurrahman
相关产品推荐
相关产品推荐

