前言 本文教程主要针对 Hexo Butterfly 主题博客中的 Twikoo 评论,按本文逻辑或许可以获取其他类型的评论,本文不作探讨。
看了其他小伙伴的 评论热评教程,觉得有点复杂,于是自己想了一个方法来实现这个功能。
沿用其他模块中用到的 swiper 轮播 使用本地缓存保存 隐藏或显示 热评,刷新或切换页面时仍 隐藏或显示 热评 增加评论的城市和日期 页面提交评论后会立即更新热评数据 点击 头像
可访问网站 点击 热评
可跳转至评论区 点击 评论内容
可跳转至改评论 此功能需关闭评论的懒加载 _config.butterfly.yml => comments.lazyload: false
,否则需等页面活动至评论区才会加载。
1 2 3 4 5 6 7 8 9 10 11 comments: use: - Twikoo text: true lazyload: false count: true card_post_count: false
修改 twikoo.pug 打开 Twikoo 评论文件 \themes\butterfly\layout\includes\third-party\comments\twikoo.pug
,添加以下内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 - const { envId, region, option } = theme.twikoo - const { use, lazyload, count } = theme.comments script. (()=>{ const init = () => { twikoo.init(Object.assign({ el: '#twikoo-wrap', envId: '!{envId}', region: '!{region}', onCommentLoaded: function () { btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)')) + setTimeout(function(){ + let tk_comment = document.querySelectorAll('.tk-comments-container .tk-comment') + if (tk_comment.length > 0) { + let html = `<div class="swiper-wrapper">` + for (let i = 0; i < tk_comment.length; i++) { + let tk_id = tk_comment[i].getAttribute('id') || '' + let tk_nick = tk_comment[i].querySelector('.tk-nick')?.innerText || '' + let tk_href = tk_comment[i].querySelector('.tk-nick')?.href || '' + let tk_avatar = tk_comment[i].querySelector('.tk-avatar-img')?.src || '' + let tk_time = tk_comment[i].querySelector('.tk-time')?.innerText || '' + let tk_city = tk_comment[i].querySelector('.tk-extras .tk-extra:first-child span:last-child')?.innerText || '' + let tk_content = tk_comment[i].querySelector('.tk-content>span:last-child')?.innerHTML || '' + tk_content = tk_content.replace(/\n/g, '') // replace \n + tk_content = tk_content.replace(/<blockquote>.*?<\/blockquote>/gi, '') // replace blockquote + tk_content = tk_content.replace(/<pre.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code + html += ` + <div class="swiper-slide"> + <div class="comment-barrage-item"> + <div class="barrage-info"> + <a class="barrage-title" title="跳转至评论区" href="#post-comment">热评</a> + <a href="${tk_href ? tk_href + '" target="_blank" rel="noopener noreferrer" title="访问 '+ tk_nick +'"' : 'javascript:void(0);"'}> + <img class="barrage-avatar" src="${tk_avatar}"> + </a> + <span class="barrage-nick">${tk_nick}</span> + <span class="barrage-city">${tk_city}</span> + <span class="barrage-time">${tk_time}</span> + <a class="barrage-close" onclick="eurkon.switchCommentBarrage()" title="隐藏热评"><i class="fa-solid fa-xmark"></i></a> + </div> + <div class="barrage-content"> + <a title="跳转至该评论" href="#${tk_id}">${tk_content}</a> + </div> + </div> + </div>` + } + html += '</div>' + let barrageContainer = document.getElementById('comment-barrage') || document.createElement('div') + barrageContainer.id = 'comment-barrage' + barrageContainer.innerHTML = html + barrageContainer.style.display = window.localStorage.getItem('commentBarrageDisplay') === 'false' ? 'none' : 'block' + document.getElementById('post-comment').appendChild(barrageContainer) + var barrageSwiper = new Swiper('#comment-barrage', { + direction: 'vertical', + loop: true, + mousewheel: true, + autoplay: { + delay: 3000, + disableOnInteraction: true, + } + }) + barrageContainer.onmouseenter = function () { + barrageSwiper.autoplay.stop() + }; + barrageContainer.onmouseleave = function () { + barrageSwiper.autoplay.start() + }; + } + }, 1000) } }, !{JSON.stringify(option)})) } const getCount = () => { const countELement = document.getElementById('twikoo-count') if(!countELement) return twikoo.getCommentsCount({ envId: '!{envId}', region: '!{region}', urls: [window.location.pathname], includeReply: false }).then(function (res) { countELement.innerText = res[0].count }).catch(function (err) { console.error(err); }); } const runFn = () => { init() !{count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : ''} } const loadTwikoo = () => { if (typeof twikoo setTimeout(runFn,0) return } getScript('!{url_for(theme.asset.twikoo)}').then(runFn) } if ('!{use[0]}' if (!{lazyload}) btf.loadComment(document.getElementById('twikoo-wrap'), loadTwikoo) else loadTwikoo() } else { window.loadOtherComment = () => { loadTwikoo() } } })()
增加自定义样式 增加自定义样式,下面 css 部分变量需自行修改,按 F12 自取。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 #comment-barrage { display : block; position : fixed; z-index : 1 ; font-size : 90% ; bottom : 1rem ; right : 2rem ; width : 306px ; height : 150px ; overflow : hidden; } @media screen and (max-width: 900px ) { #comment-barrage { display : none !important ; } } #comment-barrage .comment-barrage-item { opacity : 0 ; width : 300px ; height : fit-content; max-height : 144px ; padding : 10px ; position : absolute; margin : 0 3px ; bottom : 5px ; background : var (--card-bg); border : var (--card-border); border-radius : var (--border-radius); box-shadow : var (--box-shadow); -webkit-transition : all .3s ease-in-out; -moz-transition : all .3s ease-in-out; -o-transition : all .3s ease-in-out; -ms-transition : all .3s ease-in-out; transition : all .3s ease-in-out; } #comment-barrage .swiper-slide-active .comment-barrage-item { opacity : 1 ; } #comment-barrage .comment-barrage-item :hover { border-color : var (--main) !important ; box-shadow : var (--main-shadow) !important ; } .barrage-info { overflow : hidden; font-size : 90% ; height : 35px ; border-bottom : var (--card-border-dashed); } .barrage-info span { margin : 0 .2em ; vertical-align : middle; } .barrage-title { font-weight : bold; padding : .3em 0.5em ; background : var (--font-color); color : var (--card-bg); margin-right : .5em ; border-radius : .5em ; vertical-align : middle; } .barrage-title :hover { color : var (--second); background : var (--main); } .barrage-avatar { height : 2em ; width : 2em ; border-radius : 50% ; vertical-align : middle; } .barrage-nick { font-weight : bold; } .barrage-close { position : absolute; top : 0 ; right : 10px ; } .barrage-content { padding-top : 5px ; max-height : 95px ; height : fit-content; overflow-y : scroll; text-align : justify; word-break : break-all; } .barrage-content a { color : var (--font-color); } .barrage-content a :hover { color : var (--theme-color); } .barrage-content p { margin : 0 ; } .barrage-content img { width : 3em ; }
增加 隐藏/显示 热评 js
1 2 3 4 5 6 7 function switchCommentBarrage ( ) { let flag = window .localStorage.getItem('commentBarrageDisplay' ) document .getElementById('comment-barrage' ).style.display = flag === 'false' ? 'block' : 'none' window .localStorage.setItem('commentBarrageDisplay' , flag === 'false' ? 'undefined' : 'false' , 86400000 ) }
引入 swiper 轮播功能 修改 _config.butterfly.yml
文件
1 2 3 4 5 6 7 inject: head: - <link rel="stylesheet" href="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/Swiper/8.0.6/swiper-bundle.min.css"> - <script data-pjax src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/Swiper/8.0.6/swiper-bundle.min.js"></script>
Hexo 三连 执行 Hexo 三连
1 hexo clean && hexo g && hexo s