为什么jQuery的document.ready事件被调用两次,博客博文未正常显示?
问题根因分析
1. $(document).ready 执行两次的原因
- 最常见的原因是重复引入jQuery库:当前页面引入了
/blog/js/jquery.min.js,如果templatemo-script.js内部内嵌了额外的jQuery代码、或者jQuery UI加载时附带了重复的jQuery实例,每个jQuery实例初始化完成后都会触发自己的ready事件,导致绑定的回调执行两次。 - 小概率原因是页面被意外嵌套iframe,或者浏览器兼容问题触发了两次DOM加载完成事件,优先排查jQuery重复引入问题即可。
2. 博文不显示的核心原因
XMLHttpRequest的onreadystatechange事件会在请求的每个状态变化阶段都触发(从初始化、收到响应头、接收响应体到请求完成共触发4次),你没有加readyState === 4 && status === 200的请求完成判断,只要responseText不为空就执行解析逻辑,会在请求还没完全拿到完整的blogdata.txt内容时就提前执行判断,甚至错误触发隐藏文章的分支。再叠加ready回调执行两次、同时发送两次XHR请求的逻辑冲突,最终导致文章被隐藏。
另外你的翻页链接逻辑也存在笔误:下一页拼接的是page-1,会导致所有页的下一页都指向/blog/page0。
修复方案
第一步:修复ready执行两次问题
打开浏览器开发者工具的「网络」面板,过滤JS资源,确认是否存在多个不同版本的jQuery文件被加载,删除冗余的jQuery引用即可;如果是templatemo-script.js内嵌了重复的jQuery代码,移除内嵌部分即可。
第二步:修复博文加载逻辑
给XHR回调加上请求完成判断,同时过滤空行避免解析错误,修改后的代码如下:
$(document).ready(function() { var page = 1; var notEOF = true; var client = new XMLHttpRequest(); client.open('GET', '/blog/blogdata.txt'); client.onreadystatechange = function() { // 新增请求完成、响应正常判断 if (client.readyState === 4 && client.status === 200) { if (client.responseText != '') { // 新增过滤空行逻辑,避免换行符导致的解析错误 var txt = client.responseText.split("\n").filter(line => line.trim() !== ''); if (notEOF && txt.length > 0 && txt[page * 6 - 6] !== "EOF") { var data = txt[page * 6 - 6].split("@"); document.getElementById("link1").setAttribute("href", data[0]); document.getElementById("image1").setAttribute("src", data[1]); document.getElementById("title1").innerHTML = data[2]; document.getElementById("text1").innerHTML = data[3]; document.getElementById("tags1").innerHTML = data[4]); document.getElementById("date1").innerHTML = data[5]; } else { notEOF = false; $("#article1").hide(); } } } } var blog_html = "/blog/page"; document.getElementById("prev").setAttribute("href", blog_html.concat((page - 1).toString())); // 修复下一页链接的笔误 document.getElementById("next").setAttribute("href", blog_html.concat((page + 1).toString())); if (page == 1) { $("#prev").addClass("disabled tm-mr-20"); } if (page == 2) { document.getElementById("prev").setAttribute("href", "/blog/"); } if (!notEOF) { $("#next").addClass("disabled tm-mr-20"); } client.send(); });
内容的提问来源于stack exchange,提问作者Rushabh Mehta
相关产品推荐
相关产品推荐

