关于主题只显示每天第一个博文的的bug
问题
在布置sakura博客园主题的时候,发现这个主题只会显示每一天发布的博文中最晚发布的,其他的就不发了,很奇怪。去去翻了这个主题作者的博文也说了有这bug,但由于这个主题一直没更新,所以也一直没修复。因为比较喜欢这个主题,也抱着学习的心态,就试试能不能把这个bug修了吧。顺便把过程记录下来。
寻找问题
随笔显示问题
基本上就只有里面的main.js可以修改,那就只能从这里面下手了,由于js学的时候只是浅尝辄止,这找到主要的问题代码还是废了很大的劲。只不过还是找到了
构建整个博文的代码就在setHomeSuiBiList()
这个函数之中
javascript
setHomeSuiBiList() {
let article_list = document.getElementsByClassName('day');
let author = $(this.cnblogs.publicProfile).find('a:eq(0)').html() //作者
for (let i = article_list.length - 1; i >= 0; i--) {
let time = $('.day').find('div.dayTitle')[i].textContent.replace('年', '-').replace('月', '-').replace('日', ''); //获取年月日
let postTitle = $('.day').find('div.postTitle')[i].innerHTML;//<a class="postTitle2" href="https://www.cnblogs.com/zouwangblog/p/11194299.html">[置顶] 博客园美化</a>
let readMore = $('.day').find('a.c_b_p_desc_readmore')[i].href;//https://www.cnblogs.com/zouwangblog/p/11194299.html
let content = $('.day').find('div.c_b_p_desc')[i].textContent.replace('阅读全文', ''); //摘要
let desc = $('.day').find('div.postDesc')[i].textContent;//posted @ 2019-07-16 13:27 ふじさんの雪 阅读 (3073) 评论 (56)<a href="https://i.cnblogs.com/EditPosts.aspx?postid=11194299" rel="nofollow">编辑</a>
let readNum = desc.substring(desc.indexOf("(") + 1, desc.indexOf(")")); //阅读量
let comNum = desc.substring(desc.lastIndexOf("(") + 1, desc.lastIndexOf(")")); //评论量
let bianji = $('.day').find('div.postDesc')[i].firstElementChild.href; //获取编辑链接 https://i.cnblogs.com/EditPosts.aspx?postid=11194299
let url
let desc_img = article_list[i].getElementsByClassName('desc_img')[0];
if (desc_img !== undefined) {
url = desc_img.src;//https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190807204419622-1770363151.jpg
} else {
url = 'https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190807151203983-873040918.jpg'
}
let html = `<div class="post post-list-thumb post-list-show">` +
` <div class="post-thumb"> <a href="${readMore}"> <img class="lazyload" src="${url}" data-src="${url}"> </a></div>` +
` <div class="post-content-wrap">` +
` <div class="post-content">` +
` <div class="post-date"> <i class="iconfont icon-time"></i>发布于 ${time}</div>` +
` <div class="post-title">${postTitle}</div>` +
` <div class="post-meta"> <span><i class="iconfont icon-attention"></i>${readNum} 热度</span> <span class="comments-number"><i class="iconfont icon-mark"></i>${comNum} 条评论</span> <span><i class="iconfont icon-cc-user"></i><a href="https://www.cnblogs.com/zouwangblog/p/11157339.html"></a>${author}</span></div>` +
` <div class="float-content"><p>${content}</p>` +
` <div class="post-bottom">` +
` <a href="${readMore}" class="button-normal"><i class="iconfont icon-gengduo"></i></a>` +
` <a href="${bianji}" class="button-normal"><i class="iconfont icon-bianji"></i></a>` +
` </div>` +
` </div>` +
` </div>` +
` </div>` +
`</div>`;
$('.forFlow').prepend(html);
}
$('.post-list-thumb:odd').addClass('post-list-thumb-left')
//构建notice
const config = this.defaluts.profile;
let notice = `<div class="notice"> <i class="iconfont icon-notification"></i><div class="notice-content">${config.notice}</div></div>`
$('#main').prepend(notice);
}
这样就可以慢慢梳理思路了。我创建了四个置顶随笔+三个普通随笔,其中置顶的随笔是三天分别创建的,三个随笔是一天创建的。这个时候来看效果,很抽象,只显示了4个随笔,都是置顶的,从发布时间排序跟着排的。
这个时候就很烧脑子了,前面我没有置顶太多随笔的时候普通随笔是在的,现在只有置顶了,而且置顶的也没显示完。
仔细看整个函数感觉也没什么问题。再思考一下,既然博客园整个皮肤是靠他自带的皮肤改的,那我们去看下他没有任何皮肤的时候能否显示完,如果可以,那就能验证就是代码中识别文章是有错的。
我们来看下没有修改过的主题是怎么样的
这个时候我们发现,所有的随笔都是能正常显示的,我们再来看看html的随笔代码
day pinned
就是同一天置顶的随笔,而day
就是同一天的普通随笔,这里面包含着同一天的随笔信息
看了这个之后就很能说明问题了。
让我们看看代码是怎么获得随笔信息的,
javascript
let article_list = document.getElementsByClassName('day');
我调试了下,就会发现这段代码会获取到上面class=day
和class=day pinned
的标签内容,我去查了下getElementsByClassName
这个函数,发现参数是绝对按照参数来匹配的,至于为什么会有day pinned
也不知道,不深究了。
我们再来看看循环条件
javascript
for (let i = article_list.length - 1; i >= 0; i--)
他是按获得的div数量来循环的,那就不奇怪了,那就不奇怪了。整个获取随笔的次数跟发布随笔的天数数量一致那能不显示不出来吗?换句话说,我有四天发布了随笔,那只会获取四篇随笔,那可不嘛。
时间获取bug
然后这里面还有bug,那就是时间的获取
javascript
let time = $('.day').find('div.dayTitle')[i].textContent.replace('年', '-').replace('月', '-').replace('日', ''); //获取年月日
每一次循环都会有时间的获取,但是一天的随笔打包只会有一个dayTitle
,但是其他的信息是打包在一个
里面的,那后边的就必定获取不到时间。
图片获取bug
之后就是这个图片的获取,由于article_list必定的数量也是错的,那也得修改整个图片获取的逻辑
修复BUG
所有的问题我们都找出来了,那只用重构一下这边的代码就行了。由于原作者的代码耦合度有点高了,我用ai重构了一下,这样看起来整个功能就清晰很多了:
javascript
setHomeSuiBiList() {
let article_list = document.getElementsByClassName('day');
let author = $(this.cnblogs.publicProfile).find('a:eq(0)').html() //作者
console.log($('.day').find('div.dayTitle').length);
let article_count=($('.day').find('div.postTitle')).length;
for (let i = article_list-1; i >= 0; i--) {
let time = this.getFormattedTime($('.day').find('div.dayTitle')[i].textContent);
let postTitle = this.getPostTitle($('.day').find('div.postTitle')[i]);
let readMore = this.getReadMoreLink($('.day').find('a.c_b_p_desc_readmore')[i]);
let content = this.getContent($('.day').find('div.c_b_p_desc')[i]);
let desc = this.getPostDesc($('.day').find('div.postDesc')[i]);
let readNum = this.getReadNum(desc);
let comNum = this.getComNum(desc);
let bianji = this.getEditLink($('.day').find('div.postDesc')[i]);
let url = this.getPostImageUrl(article_list[i]);
let html = this.buildPostHtml(time, postTitle, readMore, content, desc, readNum, comNum, bianji, url, author);
$('.forFlow').prepend(html);
}
$('.post-list-thumb:odd').addClass('post-list-thumb-left');
//构建notice
const config = this.defaluts.profile;
let notice = `<div class="notice"> <i class="iconfont icon-notification"></i><div class="notice-content">${config.notice}</div></div>`
$('#main').prepend(notice);
}
/**
* 获取格式化后的时间
* @param {string} timeStr - 原始时间字符串
* @returns {string} - 格式化后的时间字符串
*/
getFormattedTime(timeStr) {
return timeStr.replace('年', '-').replace('月', '-').replace('日', '');
}
/**
* 获取文章标题
* @param {HTMLElement} postTitleElement - 包含文章标题的元素
* @returns {string} - 文章标题
*/
getPostTitle(postTitleElement) {
return postTitleElement.innerHTML;
}
/**
* 获取阅读更多链接
* @param {HTMLElement} readMoreElement - 包含阅读更多链接的元素
* @returns {string} - 阅读更多链接
*/
getReadMoreLink(readMoreElement) {
return readMoreElement.href;
}
/**
* 获取文章内容
* @param {HTMLElement} contentElement - 包含文章内容的元素
* @returns {string} - 文章内容
*/
getContent(contentElement) {
return contentElement.textContent.replace('阅读全文', '');
}
/**
* 获取文章描述
* @param {HTMLElement} descElement - 包含文章描述的元素
* @returns {string} - 文章描述
*/
getPostDesc(descElement) {
return descElement.textContent;
}
/**
* 获取阅读量
* @param {string} desc - 文章描述
* @returns {number} - 阅读量
*/
getReadNum(desc) {
return parseInt(desc.substring(desc.indexOf("(") + 1, desc.indexOf(")")));
}
/**
* 获取评论量
* @param {string} desc - 文章描述
* @returns {number} - 评论量
*/
getComNum(desc) {
return parseInt(desc.substring(desc.lastIndexOf("(") + 1, desc.lastIndexOf(")")));
}
/**
* 获取编辑链接
* @param {HTMLElement} descElement - 包含编辑链接的元素
* @returns {string} - 编辑链接
*/
getEditLink(descElement) {
return descElement.firstElementChild.href;
}
/**
* 获取文章图片链接
* @param {HTMLElement} articleElement - 文章元素
* @returns {string} - 文章图片链接
*/
getPostImageUrl(articleElement) {
let desc_img = articleElement.getElementsByClassName('desc_img')[0];
if (desc_img!== undefined) {
return desc_img.src;
} else {
return 'https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190807151203983-873040918.jpg';
}
}
/**
* 构建文章列表项的 HTML 结构
* @param {string} time - 文章发布时间
* @param {string} postTitle - 文章标题
* @param {string} readMore - 阅读更多链接
* @param {string} content - 文章内容
* @param {string} desc - 文章描述
* @param {number} readNum - 阅读量
* @param {number} comNum - 评论量
* @param {string} bianji - 编辑链接
* @param {string} url - 文章图片链接
* @param {string} author - 文章作者
* @returns {string} - 构建好的 HTML 结构
*/
重构的大致逻辑也不难。
我们先看整个置顶随笔的页面
xml
<div class="day pinned" role="article" aria-describedby="postlist_description_18530397">
<div class="dayTitle">
<a href="https://www.cnblogs.com/ENchantedN/p/archive/2024/11/06"></a>
</div>
<div class="postTitle" role="heading" aria-level="2">
<a class="postTitle2 vertical-middle pinned-post" href="https://www.cnblogs.com/ENchantedN/p/18530442">
<span>
<span class="pinned-post-mark">[置顶]</span>
置顶4
</span>
</a>
</div>
<div class="postCon">
<div class="c_b_p_desc" id="postlist_description_18530442">
摘要: <img src="./Be_Somebody - 博客园_files/3033596-20241106204215268-744098495.png" alt="置顶4" class="desc_img">
置顶4 <a href="https://www.cnblogs.com/ENchantedN/p/18530442" class="c_b_p_desc_readmore">阅读全文</a>
</div>
</div>
<div class="clear"></div>
<div class="postDesc">posted @ 2024-11-06 16:13
Be_Somebody
<span data-post-id="18530442" class="post-view-count">阅读(4)</span>
<span data-post-id="18530442" class="post-comment-count">评论(0)</span>
<span data-post-id="18530442" class="post-digg-count">推荐(0)</span>
<a href="https://i.cnblogs.com/EditPosts.aspx?postid=18530442" rel="nofollow">
编辑
</a>
</div>
<div class="clear"></div>
<div class="postSeparator"></div>
<div class="postTitle" role="heading" aria-level="2">
<a class="postTitle2 vertical-middle pinned-post" href="https://www.cnblogs.com/ENchantedN/p/18530395">
<span>
<span class="pinned-post-mark">[置顶]</span>
一天置顶1
</span>
</a>
</div>
<div class="postCon">
<div class="c_b_p_desc" id="postlist_description_18530395">
摘要:
一天置顶1 <a href="https://www.cnblogs.com/ENchantedN/p/18530395" class="c_b_p_desc_readmore">阅读全文</a>
</div>
</div>
<div class="clear"></div>
<div class="postDesc">posted @ 2024-11-06 15:58
Be_Somebody
<span data-post-id="18530395" class="post-view-count">阅读(0)</span>
<span data-post-id="18530395" class="post-comment-count">评论(0)</span>
<span data-post-id="18530395" class="post-digg-count">推荐(0)</span>
<a href="https://i.cnblogs.com/EditPosts.aspx?postid=18530395" rel="nofollow">
编辑
</a>
</div>
<div class="clear"></div>
<div class="postSeparator"></div>
<div class="postTitle" role="heading" aria-level="2">
<a class="postTitle2 vertical-middle pinned-post" href="https://www.cnblogs.com/ENchantedN/p/18530397">
<span>
<span class="pinned-post-mark">[置顶]</span>
一天置顶2
</span>
</a>
</div>
<div class="postCon">
<div class="c_b_p_desc" id="postlist_description_18530397">
摘要: <img src="./Be_Somebody - 博客园_files/3033596-20241106204443382-343604796.jpg" alt="一天置顶2" class="desc_img">
一天置2 <a href="https://www.cnblogs.com/ENchantedN/p/18530397" class="c_b_p_desc_readmore">阅读全文</a>
</div>
</div>
<div class="clear"></div>
<div class="postDesc">posted @ 2024-11-06 15:58
Be_Somebody
<span data-post-id="18530397" class="post-view-count">阅读(0)</span>
<span data-post-id="18530397" class="post-comment-count">评论(0)</span>
<span data-post-id="18530397" class="post-digg-count">推荐(0)</span>
<a href="https://i.cnblogs.com/EditPosts.aspx?postid=18530397" rel="nofollow">
编辑
</a>
</div>
<div class="clear"></div>
</div>
我们容易发现,每个随笔必会有postTitle
这个标签,那么我们只用给postTitle
计数就能解决文章数不同的问题,这个时候再换掉for循环的article_list-1
javascript
let article_count = 0;
document.querySelectorAll('.day').forEach(day => {
article_count += day.querySelectorAll('.postTitle').length;
});
这个解决了之后就是时间获取的问题,这里我在贴出普通随笔的页面代码
html
<div class="day" role="article" aria-describedby="postlist_description_18525705">
<div class="dayTitle">
<a href="https://www.cnblogs.com/ENchantedN/p/archive/2024/11/04">2024年11月4日
</a>
</div>
<div class="postTitle" role="heading" aria-level="2">
<a class="postTitle2 vertical-middle" href="https://www.cnblogs.com/ENchantedN/p/18525710">
<span>
测试3
</span>
</a>
</div>
<div class="postCon">
<div class="c_b_p_desc" id="postlist_description_18525710">
摘要:
测试3 <a href="https://www.cnblogs.com/ENchantedN/p/18525710" class="c_b_p_desc_readmore">阅读全文</a>
</div>
</div>
<div class="clear"></div>
<div class="postDesc">posted @ 2024-11-04 16:57
Be_Somebody
<span data-post-id="18525710" class="post-view-count">阅读(8)</span>
<span data-post-id="18525710" class="post-comment-count">评论(0)</span>
<span data-post-id="18525710" class="post-digg-count">推荐(0)</span>
<a href="https://i.cnblogs.com/EditPosts.aspx?postid=18525710" rel="nofollow">
编辑
</a>
</div>
<div class="clear"></div>
<div class="postSeparator"></div>
<div class="postTitle" role="heading" aria-level="2">
<a class="postTitle2 vertical-middle" href="https://www.cnblogs.com/ENchantedN/p/18525707">
<span>
测试2
</span>
</a>
</div>
<div class="postCon">
<div class="c_b_p_desc" id="postlist_description_18525707">
摘要:
测试2 <a href="https://www.cnblogs.com/ENchantedN/p/18525707" class="c_b_p_desc_readmore">阅读全文</a>
</div>
</div>
<div class="clear"></div>
<div class="postDesc">posted @ 2024-11-04 16:57
Be_Somebody
<span data-post-id="18525707" class="post-view-count">阅读(0)</span>
<span data-post-id="18525707" class="post-comment-count">评论(0)</span>
<span data-post-id="18525707" class="post-digg-count">推荐(0)</span>
<a href="https://i.cnblogs.com/EditPosts.aspx?postid=18525707" rel="nofollow">
编辑
</a>
</div>
<div class="clear"></div>
<div class="postSeparator"></div>
<div class="postTitle" role="heading" aria-level="2">
<a class="postTitle2 vertical-middle" href="https://www.cnblogs.com/ENchantedN/p/18525705">
<span>
测试1
</span>
</a>
</div>
<div class="postCon">
<div class="c_b_p_desc" id="postlist_description_18525705">
摘要: <img src="./Be_Somebody - 博客园_files/3033596-20241106204426204-456357718.jpg" alt="测试1" class="desc_img">
测试1 <a href="https://www.cnblogs.com/ENchantedN/p/18525705" class="c_b_p_desc_readmore">阅读全文</a>
</div>
</div>
<div class="clear"></div>
<div class="postDesc">posted @ 2024-11-04 16:57
Be_Somebody
<span data-post-id="18525705" class="post-view-count">阅读(0)</span>
<span data-post-id="18525705" class="post-comment-count">评论(0)</span>
<span data-post-id="18525705" class="post-digg-count">推荐(0)</span>
<a href="https://i.cnblogs.com/EditPosts.aspx?postid=18525705" rel="nofollow">
编辑
</a>
</div>
<div class="clear"></div>
</div>
我们能发现跟置顶的随笔不同的是,普通随笔有直接的时间dayTitle
标签可以使用,但是置顶的是没有的,那我们只能另寻他路了,值得注意的是postDesc
里面是有时间的,那么我们就可以直接拆分以下就能使用了,我们直接把time
的定义放在desc的下面,这样就可以直接传入desc
的值切割就能用了
javascript
let desc = this.getPostDesc($('.day').find('div.postDesc')[i]);
let time = this.getFormattedTime(desc);
javascript
getFormattedTime(timeStr) {
return timeStr.substring(8, 19);
}
最后一个就是图片的获取了,我们再次比对有自定义图片和没有自定义图片的c_b_p_desc
,在有自定义图片的随笔中的c_b_p_desc
里面是有一个img的标签的,那么我们只用判断在这里面的c_b_p_desc
是否有img标签就提取出来,没有我们直接就放入默认的图片就行
javascript
let url = this.getPostImageUrl(document.querySelectorAll('.c_b_p_desc')[i]);
javascript
getPostImageUrl(desc) {
const img = desc.querySelector('.desc_img');
if (img) {
return img.src;
} else {
return 'https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190807151203983-873040918.jpg';
}
}
最后整合一下,修复的代码如下:
javascript
setHomeSuiBiList() {
let article_count = 0;
let author = $(this.cnblogs.publicProfile).find('a:eq(0)').html() //作者
document.querySelectorAll('.day').forEach(day => {
article_count += day.querySelectorAll('.postTitle').length;
});
for (let i = article_count-1; i >= 0; i--) {
let postTitle = this.getPostTitle($('.day').find('div.postTitle')[i]);
let readMore = this.getReadMoreLink($('.day').find('a.c_b_p_desc_readmore')[i]);
let content = this.getContent($('.day').find('div.c_b_p_desc')[i]);
let desc = this.getPostDesc($('.day').find('div.postDesc')[i]);
let time = this.getFormattedTime(desc);
let readNum = this.getReadNum(desc);
let comNum = this.getComNum(desc);
let bianji = this.getEditLink($('.day').find('div.postDesc')[i]);
let url = this.getPostImageUrl(document.querySelectorAll('.c_b_p_desc')[i]);
let html = this.buildPostHtml(time, postTitle, readMore, content, desc, readNum, comNum, bianji, url, author);
$('.forFlow').prepend(html);
}
$('.post-list-thumb:odd').addClass('post-list-thumb-left');
//构建notice
const config = this.defaluts.profile;
let notice = `<div class="notice"> <i class="iconfont icon-notification"></i><div class="notice-content">${config.notice}</div></div>`
$('#main').prepend(notice);
}
/**
* 获取格式化后的时间
* @param {string} timeStr - 原始时间字符串
* @returns {string} - 格式化后的时间字符串
*/
/**getFormattedTime(timeStr) {
return timeStr.replace('年', '-').replace('月', '-').replace('日', '');
}**/
getFormattedTime(timeStr) {
return timeStr.substring(8, 19);
}
/**
* 获取文章标题
* @param {HTMLElement} postTitleElement - 包含文章标题的元素
* @returns {string} - 文章标题
*/
getPostTitle(postTitleElement) {
return postTitleElement.innerHTML;
}
/**
* 获取阅读更多链接
* @param {HTMLElement} readMoreElement - 包含阅读更多链接的元素
* @returns {string} - 阅读更多链接
*/
getReadMoreLink(readMoreElement) {
return readMoreElement.href;
}
/**
* 获取文章内容
* @param {HTMLElement} contentElement - 包含文章内容的元素
* @returns {string} - 文章内容
*/
getContent(contentElement) {
return contentElement.textContent.replace('阅读全文', '');
}
/**
* 获取文章描述
* @param {HTMLElement} descElement - 包含文章描述的元素
* @returns {string} - 文章描述
*/
getPostDesc(descElement) {
return descElement.textContent;
}
/**
* 获取阅读量
* @param {string} desc - 文章描述
* @returns {number} - 阅读量
*/
getReadNum(desc) {
return parseInt(desc.substring(desc.indexOf("(") + 1, desc.indexOf(")")));
}
/**
* 获取评论量
* @param {string} desc - 文章描述
* @returns {number} - 评论量
*/
getComNum(desc) {
return parseInt(desc.substring(desc.lastIndexOf("(") + 1, desc.lastIndexOf(")")));
}
/**
* 获取编辑链接
* @param {HTMLElement} descElement - 包含编辑链接的元素
* @returns {string} - 编辑链接
*/
getEditLink(descElement) {
return descElement.firstElementChild.href;
}
/**
* 获取文章图片链接
* @param {HTMLElement} articleElement - 文章元素
* @returns {string} - 文章图片链接
*/
getPostImageUrl(desc) {
const img = desc.querySelector('.desc_img');
//let desc_img = articleElement.getElementsByClassName('desc_img')[0];
if (img) {
return img.src;
} else {
return 'https://img2018.cnblogs.com/blog/1646268/201908/1646268-20190807151203983-873040918.jpg';
}
}
/**
* 构建文章列表项的 HTML 结构
* @param {string} time - 文章发布时间
* @param {string} postTitle - 文章标题
* @param {string} readMore - 阅读更多链接
* @param {string} content - 文章内容
* @param {string} desc - 文章描述
* @param {number} readNum - 阅读量
* @param {number} comNum - 评论量
* @param {string} bianji - 编辑链接
* @param {string} url - 文章图片链接
* @param {string} author - 文章作者
* @returns {string} - 构建好的 HTML 结构
*/
其实里面还有一些大大小小bug,但是这位博主在这个随笔里面已经解决了博客园Sakura主题美化中BUG修复方法 - CodeFan* - 博客园