教程 Hexo 即刻短文(瀑布流)部署方案 安知鱼 2022-10-26 2023-08-01 butterfly 即刻短文(瀑布流)部署方案。希望能给各位看客提供魔改思路。
todolist 支持度 图片灯箱 ✅ 多图片多行显示 ✅ 外部链接 ✅ 瀑布流 ✅ 首页滚动 ✅ 快速评论 ✅ 本地修改 yml 发布 ✅ aplayer 单曲音乐 ✅ 插件版本 ❌
点击查看参考教程 注意 ⚠️ 该教程仅为博主目前使用的方法, 如需移植还需自行修改 css 变量, 以下为博主自用 css 变量, 可自行修改为自己喜欢的颜色。
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 :root { --anzhiyu-theme-op : #4259ef23 ; --anzhiyu-gray-op : #9999992b ; --anzhiyu-theme-top : var (--anzhiyu-theme); --anzhiyu-white : #fff ; --anzhiyu-white-op : rgba (255 , 255 , 255 , 0.2 ); --anzhiyu-black : #000 ; --anzhiyu-black-op : rgba (0 , 0 , 0 , 0.2 ); --anzhiyu-none : rgba (0 , 0 , 0 , 0 ); --anzhiyu-gray : #999999 ; --anzhiyu-yellow : #ffc93e ; --anzhiyu-border-radius : 8px ; --anzhiyu-main : var (--anzhiyu-theme); --anzhiyu-main-op : var (--anzhiyu-theme-op); --anzhiyu-shadow-theme : 0 8px 12px -3px var (--anzhiyu-theme-op); --anzhiyu-shadow-main : 0 8px 12px -3px var (--anzhiyu-main-op); --anzhiyu-shadow-blue : 0 8px 12px -3px rgba (40 , 109 , 234 , 0.2 ); --anzhiyu-shadow-white : 0 8px 12px -3px rgba (255 , 255 , 255 , 0.2 ); --anzhiyu-shadow-black : 0 0 12px 4px rgba (0 , 0 , 0 , 0.05 ); --anzhiyu-shadow-yellow : 0px 38px 77px -26px rgba (255 , 201 , 62 , 0.12 ); --anzhiyu-shadow-red : 0 8px 12px -3px #ee7d7936 ; --anzhiyu-shadow-green : 0 8px 12px -3px #87ee7936 ; --anzhiyu-shadow-border : 0 8px 16px -4px #2c2d300c ; --anzhiyu-shadow-blackdeep : 0 2px 16px -3px rgba (0 , 0 , 0 , 0.15 ); --anzhiyu-logo-color : linear-gradient (215deg , #4584ff 30% , #ff7676 70% ); --style-border : 1px solid var (--anzhiyu-card-border); --anzhiyu-blue-main : #3b70fc ; --style-border-hover : 1px solid var (--anzhiyu-main); --style-border-dashed : 1px dashed var (--anzhiyu-theme-op); --style-border-avatar : 4px solid var (--anzhiyu-background); --style-border-always : 1px solid var (--anzhiyu-card-border); --style-border-none : 1px solid transparent; --anzhiyu-white-acrylic1 : #fefeff !important ; --anzhiyu-white-acrylic2 : #fcfdff !important ; --anzhiyu-black-acrylic2 : #08080a !important ; --anzhiyu-black-acrylic1 : #0b0b0e !important ; --anzhiyu-main-none : #b8b8b800 !important ; } [data-theme="light" ] { --anzhiyu-theme : #3b70fc ; --anzhiyu-theme-deep : #1856fb ; --anzhiyu-theme-op : #4259ef23 ; --anzhiyu-blue : #3b70fc ; --anzhiyu-red : #d8213c ; --anzhiyu-pink : #ff7c7c ; --anzhiyu-green : #57bd6a ; --anzhiyu-fontcolor : #363636 ; --anzhiyu-background : #f7f9fe ; --anzhiyu-reverse : #000 ; --anzhiyu-maskbg : rgba (255 , 255 , 255 , 0.6 ); --anzhiyu-maskbgdeep : rgba (255 , 255 , 255 , 0.85 ); --anzhiyu-hovertext : var (--anzhiyu-theme); --anzhiyu-ahoverbg : #f7f7fa ; --anzhiyu-lighttext : var (--anzhiyu-main); --anzhiyu-secondtext : rgba (60 , 60 , 67 , 0.6 ); --anzhiyu-scrollbar : rgba (60 , 60 , 67 , 0.4 ); --anzhiyu-card-btn-bg : #edf0f7 ; --anzhiyu-post-blockquote-bg : #fafcff ; --anzhiyu-post-tabs-bg : #f2f5f8 ; --anzhiyu-secondbg : #f1f3f8 ; --anzhiyu-shadow-nav : 0 5px 12px -5px rgba (102 , 68 , 68 , 0.05 ); --anzhiyu-card-bg : #fff ; --anzhiyu-shadow-lightblack : 0 5px 12px -5px rgba (102 , 68 , 68 , 0 ); --anzhiyu-shadow-light2black : 0 5px 12px -5px rgba (102 , 68 , 68 , 0 ); --anzhiyu-card-border : #e3e8f7 ; } [data-theme="dark" ] { --global-bg : #191919 ; --anzhiyu-theme : #0084ff ; --anzhiyu-theme-deep : #0076e5 ; --anzhiyu-theme-op : #0084ff23 ; --anzhiyu-blue : #0084ff ; --anzhiyu-red : #ff3842 ; --anzhiyu-pink : #ff7c7c ; --anzhiyu-green : #57bd6a ; --anzhiyu-fontcolor : #f7f7fa ; --anzhiyu-background : #18171d ; --anzhiyu-reverse : #fff ; --anzhiyu-maskbg : rgba (0 , 0 , 0 , 0.6 ); --anzhiyu-maskbgdeep : rgba (0 , 0 , 0 , 0.85 ); --anzhiyu-hovertext : #0a84ff ; --anzhiyu-ahoverbg : #fff ; --anzhiyu-lighttext : #f2b94b ; --anzhiyu-secondtext : #a1a2b8 ; --anzhiyu-scrollbar : rgba (200 , 200 , 223 , 0.4 ); --anzhiyu-card-btn-bg : #30343f ; --anzhiyu-post-blockquote-bg : #000 ; --anzhiyu-post-tabs-bg : #121212 ; --anzhiyu-secondbg : #30343f ; --anzhiyu-shadow-nav : 0 5px 20px 0px rgba (28 , 28 , 28 , 0.4 ); --anzhiyu-card-bg : #1d1b26 ; --anzhiyu-shadow-lightblack : 0 5px 12px -5px rgba (102 , 68 , 68 , 0 ); --anzhiyu-shadow-light2black : 0 5px 12px -5px rgba (102 , 68 , 68 , 0 ); --anzhiyu-card-border : #42444a ; }
预览 魔改有风险, 魔改前注意备份。此篇魔改需一定代码能力。
创建数据 创建 source/_data/essay.yml
下面是我的演示数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 - class_name: 即刻短文 essay_list: - content: 终于把相册集搞定了, 耶✌️, 瀑布流在滑动滚动条一个视口范围上下100的情况执行一次, 到底部停止监听让性能高了好多,再也不会布局混乱🤪了 date: 2022 /10/25 link: https://blog.anheyu.com/album/ - content: 搜索🔍支持缩略图显示啦(默认获取文章内容的第一张图片) date: 2022 /10/23 08 :00:00 from: 安知鱼 - content: 遇见彩虹🌈吃定彩虹 date: 2022 /10/23 10 :00:00 image: - https://img02.anheyu.com/adminuploads/1/2022/10/23/6354ea92960ef.webp - content: ThreeJs API真多丫 date: 2022 /10/19 - content: 歌曲推荐 date: 2022 /09/25 aplayer: server: tencent id: 001FGQba3i10mw
数据参数释义 参数 备选值/类型 释义 class_name String 【可选】标识符,无实际意义,选填 essay_list Array 【必选】即刻短文数据列表 essay_list.content String 【必选】短文 文字内容 essay_list.date Time 【必选】短文发布时间 格式建议为 2022/10/26 08:00:00
essay_list.image Array 【可选】短文图片内容, 可填写多张图片 essay_list.from String 【可选】短文 来自何处, 当然也可以填任何你想填写的标识 essay_list.link String 【可选】外部链接 essay_list.aplayer Array 【可选】aplayer 播放器的单曲音乐, 需 aplayer 支持 essay_list.aplayer.server String 【essay_list.aplayer 后必选】aplayer 服务商 essay_list.aplayer.id String 【essay_list.aplayer 后必选】单曲 id
创建 md 页面文件 创建source/essay/index.md
来生成页面 page
1 2 3 4 5 6 7 8 --- title: 即刻短文 date: 2020-07-22 22:06:17 comments: true aside: false top_img: false type: essay ---
创建 dom 文件 创建themes/butterfly/layout/includes/page/essay.pug
, 页面内容, 注意该页面中可能存在部分fontawesome 图标
需要自行替换。
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 #essay_page .author-content.author-content-item.essayPage.single .card-content .author-content-item-tips 即刻短文 span.author-content-item-title 咸鱼的日常生活。 .content-bottom .tips 使用 即刻短文静态部署版 构建 .banner-button-group a.banner-button(onclick='pjax.loadUrl("/about/")', data-pjax-state) i.fas.fa-circle-right(style='font-size: 1.5rem') span.banner-button-text 关于我 #bber section.timeline.page-1 ul#waterfall.list each i in site.data.essay each item, index in i.essay_list if index < 30 li.bber-item .bber-content p.datacont= item.content if item.image .bber-container-img each iten, indey in item.image a.bber-content-img(href=item.image[indey], target="_blank", data-fancybox="gallery", data-caption="") img(src=item.image[indey]) .bber-content-noimg .bber-content-noimg .bber-content-noimg if item.aplayer .bber-music .aplayer.no-destroy(data-id=item.aplayer.id data-server=item.aplayer.server data-type="song" data-order="list" data-preload="none" data-autoplay="false" data-mutex="true" data-theme='var(--anzhiyu-main)') hr .bber-bottom .bber-info .bber-info-time - var datedata = new Date(item.date).toISOString() i.far.fa-clock time.datatime(datetime= item.date)= datedata if item.link a.bber-content-link(target="_blank", title="跳转到短文指引的链接", href=item.link, rel="external nofollow") i.fas.fa-link | 链接 if item.from .bber-info-from i.fas.fa-fire span=item.from .bber-reply(onclick="anzhiyu.commentText(" + `'${item.content}'` + ")") i.fa-solid.fa-message #bber-tips(style='color: var(--anzhiyu-secondtext);') | - 只展示最近30条短文 -
修改 Page 文件 修改themes/butterfly/layout/page.pug
来使页面内容匹配
在 case page.type
子项里面添加, 注意缩进
1 2 3 4 5 6 7 8 9 case page.type + when 'essay' + include includes/page/essay.pug when 'tags' include includes/page/tags.pug when 'link' include includes/page/flink.pug when 'categories' include includes/page/categories.pug
加入 css 此处不在赘述如何创建自定义css
, 不会的可以去看 https://www.bilibili.com/video/BV1rT411w7gj/?spm_id_from=333.999.0.0 创建source/css/essay_page/essay_page.css
, 然后在_config.butterfly.yml
中的inject
下的head
引入, 注意缩进
1 2 3 inject: head: - <link rel="stylesheet" href="/css/essay_page/essay_page.css">
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 #page :has (#essay_page ) { border : 0 ; box-shadow : none !important ; padding : 0 !important ; background : transparent !important ; } #page :has (#essay_page ) .page-title { display : none; } #web_bg ~ .page :has (#essay_page ) { background : var (--anzhiyu-background); } #bber .bber-container-img { display : flex; align-items : center; justify-content : space-around; width : 100% ; flex-wrap : wrap; margin-bottom : 0.3rem ; } #bber .bber-container-img .bber-content-noimg { width : calc (100% / 4 - 5px ); } #bber .bber-content-img img { object-fit : cover; max-height : 100% ; border-radius : 12px ; } #bber .bber-content-img { height : 100px ; border-radius : 12px ; overflow : hidden; display : flex; position : relative; width : calc (100% / 4 - 5px ); margin-bottom : 10px ; } #bber .bber-content .datacont { order : 0 ; font-size : 0.8rem ; font-weight : 700 ; color : var (--anzhiyu-fontcolor); width : 100% ; line-height : 1.38 ; border-radius : 12px ; margin-bottom : 0.5rem ; display : flex; flex-direction : column; text-align : justify; } #bber p { margin : 0px ; } #bber div .bber-content { display : flex; flex-flow : wrap; border-radius : 12px ; width : 100% ; height : 100% ; } #bber .timeline ul li .bber-item { position : relative; width : 32% ; border : var (--style-border-always); border-radius : 12px ; padding : 1rem 1rem 0.5rem ; transition : all 0.3s ease 0s ; display : flex; flex-flow : column nowrap; justify-content : space-between; align-items : flex-start; background : var (--anzhiyu-card-bg); box-shadow : var (--anzhiyu-shadow-border); margin-right : 2% ; } #bber .timeline #waterfall .show { opacity : 1 ; } #bber .timeline #waterfall { opacity : 0 ; transition : all 0.3s ease 0s ; } #bber ul .list { display : flex; flex-flow : row wrap; justify-content : space-between; } #bber { margin-top : 1rem ; width : 100% ; } #bber > section > ul > li .bber-item { margin-bottom : 1rem ; } #bber-tips { font-size : 14px ; display : flex; justify-content : center; margin-top : 1rem ; } #bber .timeline ul li .bber-item hr { display : flex; position : relative; margin : 8px 0px ; border : 1px dashed var (--anzhiyu-theme-op); width : 100% ; } #bber .bber-info { display : flex; align-items : center; } #bber > section > ul > li > div .bber-info-time ,#bber > section > ul > li > div .bber-info-from { color : var (--anzhiyu-fontcolor); font-size : 0.7rem ; background-color : var (--anzhiyu-gray-op); padding : 0px 8px ; border-radius : 20px ; cursor : default; display : flex; align-items : center; } #bber .bber-info .far .fa-clock { margin-right : 4px ; } #bber > section > ul > li > div .bber-info-from span ,#bber > section > ul > li > div .bber-info-from { margin-left : 4px ; } #bber .bber-bottom { display : flex; justify-content : space-between; width : 100% ; margin-top : 10px ; } #bber .bber-bottom .bber-reply { cursor : pointer; } #bber .timeline ul li .bber-item :hover { border : var (--style-border-hover); } #bber .bber-content-link { display : flex; margin-left : 0.5rem ; font-size : 0.7rem ; align-items : center; background-color : rgba (245 , 108 , 108 , 0.13 ); color : rgb (245 , 108 , 108 ); padding : 0px 8px ; border-radius : 20px ; } #bber .bber-content-link i { margin-right : 3px ; } #bber .bber-content-link :hover { background-color : var (--anzhiyu-main); color : var (--anzhiyu-white); } #bber .bber-music { width : 100% ; height : 90px ; margin : 0.5rem 0 ; border-radius : 8px ; overflow : hidden; border : var (--style-border-always); background : var (--anzhiyu-secondbg); } #bber .aplayer { margin : 0 ; } #bber .aplayer .aplayer-withlrc .aplayer-pic { height : 82px ; width : 82px ; margin : 4px ; border-radius : 4px ; } .bber-music .aplayer .aplayer-withlrc .aplayer-info { padding : 5px 7px 0 ; } #bber .aplayer .aplayer-info .aplayer-music { height : 23px ; } #bber .aplayer .aplayer-info .aplayer-music .aplayer-title { font-size : 0.8rem ; font-weight : 700 ; margin : 0 ; color : var (--anzhiyu-fontcolor); } #bber .aplayer .aplayer-info .aplayer-controller { align-items : center; } #bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap { padding : 0 ; } #bber .aplayer .aplayer-info .aplayer-controller .aplayer-time { position : initial; } #bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar { background : var (--anzhiyu-gray); height : 8px ; border-radius : 12px ; transition : 0.3s ; overflow : hidden; } #bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-loaded { height : 100% ; border-radius : 12px ; } #bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played { height : 100% ; border-radius : 12px ; } #bber .aplayer .aplayer-info .aplayer-controller .aplayer-bar-wrap .aplayer-bar .aplayer-played .aplayer-thumb { display : none; } #bber .aplayer .aplayer-info .aplayer-controller .aplayer-time { position : initial; } .author-content .author-content-item .essayPage { height : 19rem ; background : url (https://img02.anheyu.com/adminuploads/1/2022/08/21/630249e2df20f.jpg ) left 28% / cover no-repeat; color : var (--anzhiyu-white); overflow : hidden; margin-top : 0px ; } #page :has (#essay_page ) .author-content-item .card-content .banner-button-group .banner-button :hover { color : var (--anzhiyu-white); border-radius : 20px !important ; } @media screen and (max-width : 1300px ) { #bber .timeline ul li .bber-item { width : 49% ; margin-right : 1% ; } } @media screen and (max-width : 768px ) { #bber .timeline ul li .bber-item { width : 100% ; margin-right : 0px ; } } [data-theme="dark" ] #bber .bber-music .aplayer ,[data-theme="dark" ] #bber .aplayer .aplayer-lrc :before ,[data-theme="dark" ] #bber .aplayer .aplayer-lrc :after { background : var (--anzhiyu-card-bg); color : var (--anzhiyu-fontcolor); } #bber .aplayer .aplayer-lrc p { color : var (--anzhiyu-fontcolor); }
js 处理 新建一个 js 文件用来处理即刻短文的逻辑, 或者写在公共 js 中也可以, 博主写在公共 js 中, 即custom.js
, 该 js 在_config.butterfly.yml
中的inject
使用如下方式引入, 加入了data-pjax
, 并且开启了站点的pjax
, 然后再引入waterfall.js
用于处理瀑布流。
1 2 3 4 5 inject: bottom: - <script async data-pjax src="/js/custom.js"></script> - <script async data-pjax src="/js/waterfall/waterfall.js"></script>
1 2 3 4 5 6 pjax: enable: true exclude:
新建 source/js/waterfall/waterfall.js
内容如下
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 function waterfall (a ) { function b (a, b ) { var c = window .getComputedStyle (b); return parseFloat (c["margin" + a]) || 0 ; } function c (a ) { return a + "px" ; } function d (a ) { return parseFloat (a.style .top ); } function e (a ) { return parseFloat (a.style .left ); } function f (a ) { return a.clientWidth ; } function g (a ) { return a.clientHeight ; } function h (a ) { return d (a) + g (a) + b ("Bottom" , a); } function i (a ) { return e (a) + f (a) + b ("Right" , a); } function j (a ) { a = a.sort (function (a, b ) { return h (a) === h (b) ? e (b) - e (a) : h (b) - h (a); }); } function k (b ) { f (a) != t && (b.target .removeEventListener (b.type , arguments .callee ), waterfall (a)); } "string" == typeof a && (a = document .querySelector (a)); var l = [].map .call (a.children , function (a ) { return (a.style .position = "absolute" ), a; }); a.style .position = "relative" ; var m = []; l.length && ((l[0 ].style .top = "0px" ), (l[0 ].style .left = c (b ("Left" , l[0 ]))), m.push (l[0 ])); for (var n = 1 ; n < l.length ; n++) { var o = l[n - 1 ], p = l[n], q = i (o) + f (p) <= f (a); if (!q) break ; (p.style .top = o.style .top ), (p.style .left = c (i (o) + b ("Left" , p))), m.push (p); } for (; n < l.length ; n++) { j (m); var p = l[n], r = m.pop (); (p.style .top = c (h (r) + b ("Top" , p))), (p.style .left = c (e (r))), m.push (p); } j (m); var s = m[0 ]; a.style .height = c (h (s) + b ("Bottom" , s)); var t = f (a); window .addEventListener ? window .addEventListener ("resize" , k) : (document .body .onresize = k); }
custom.js
内容如下
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 var percentFlag = false ; function essayScroll ( ) { let a = document .documentElement .scrollTop || window .pageYOffset ; const waterfallResult = a % document .documentElement .clientHeight ; result <= 99 || (result = 99 ); if ( !percentFlag && waterfallResult + 100 >= document .documentElement .clientHeight && document .querySelector ("#waterfall" ) ) { setTimeout (() => { waterfall ("#waterfall" ); }, 500 ); } else { setTimeout (() => { document .querySelector ("#waterfall" ) && waterfall ("#waterfall" ); }, 500 ); } const r = window .scrollY + document .documentElement .clientHeight ; let p = document .getElementById ("post-comment" ) || document .getElementById ("footer" ); (p.offsetTop + p.offsetHeight / 2 < r || 90 < result) && (percentFlag = true ); } function replaceAll (e, n, t ) { return e.split (n).join (t); } var anzhiyu = { diffDate : function (d, more = false ) { const dateNow = new Date (); const datePost = new Date (d); const dateDiff = dateNow.getTime () - datePost.getTime (); const minute = 1000 * 60 ; const hour = minute * 60 ; const day = hour * 24 ; const month = day * 30 ; let result; if (more) { const monthCount = dateDiff / month; const dayCount = dateDiff / day; const hourCount = dateDiff / hour; const minuteCount = dateDiff / minute; if (monthCount >= 1 ) { result = datePost.toLocaleDateString ().replace (/\//g , "-" ); } else if (dayCount >= 1 ) { result = parseInt (dayCount) + " " + GLOBAL_CONFIG .date_suffix .day ; } else if (hourCount >= 1 ) { result = parseInt (hourCount) + " " + GLOBAL_CONFIG .date_suffix .hour ; } else if (minuteCount >= 1 ) { result = parseInt (minuteCount) + " " + GLOBAL_CONFIG .date_suffix .min ; } else { result = GLOBAL_CONFIG .date_suffix .just ; } } else { result = parseInt (dateDiff / day); } return result; }, changeTimeInEssay : function ( ) { document .querySelector ("#bber" ) && document .querySelectorAll ("#bber time" ).forEach (function (e ) { var t = e, datetime = t.getAttribute ("datetime" ); (t.innerText = anzhiyu.diffDate (datetime, true )), (t.style .display = "inline" ); }); }, reflashEssayWaterFall : function ( ) { document .querySelector ("#waterfall" ) && setTimeout (function ( ) { waterfall ("#waterfall" ); document .getElementById ("waterfall" ).classList .add ("show" ); }, 500 ); }, commentText : function (e ) { if (e == "undefined" || e == "null" ) e = "好棒!" ; var n = document .getElementsByClassName ("el-textarea__inner" )[0 ], t = document .createEvent ("HTMLEvents" ); if (!n) return ; t.initEvent ("input" , !0 , !0 ); var o = replaceAll (e, "\n" , "\n> " ); (n.value = "> " + o + "\n\n" ), n.dispatchEvent (t); var i = document .querySelector ("#post-comment" ).offsetTop ; window .scrollTo (0 , i - 80 ), n.focus (), n.setSelectionRange (-1 , -1 ), document .getElementById ("comment-tips" ) && document .getElementById ("comment-tips" ).classList .add ("show" ); }, }; anzhiyu.changeTimeInEssay (); anzhiyu.reflashEssayWaterFall ();
其中anzhiyu
变量中存储的四个方法
diffDate
为处理时间的方法,其实 btf 中也有,只是不太喜欢那个的显示方式,就改成现在这个了。changeTimeInEssay
初始化即刻时间reflashEssayWaterFall
处理瀑布流显示commentText
处理点击跳转评论并添加评论方法essayScroll
为检查滚动条卷去一个视口高度的 100 范围内执行一次, 滑动到底部或评论区取消监听执行。此处博主未做 else 处理取消监听, 如果有写percent
函数监听滑动可以一起写在同一个方法里面。(博主就是写在同一个方法里面), 如果即刻文章很少的话其实是可以不监听滑动的, 即只显示近 30 条, 因为进入页面后会执行一次瀑布流, 页面不会乱, 但是如果您把 essay.pug
中 17 行左右修改后可以达到无限的效果就会出现 dom 结构还没渲染瀑布流就已经执行完了的情况就需要监听滚动来再次执行瀑布流以完成布局。
首页滚动显示即刻(可选) 创建 themes/butterfly/layout/includes/bbTimeList.pug
, 部分fontawesome图标
可能需要您自行修改。
1 2 3 4 5 6 7 8 9 10 11 12 #bbTimeList.bbTimeList.container svg.icon.bber-logo.iconfont.icon-chrome(onclick=`pjax.loadUrl("/essay/")`,title="即刻短文",aria-hidden="true") use(xlink:href="#icon-chrome") #bbtalk.swiper-container.swiper-no-swiping.essay_bar_swiper_container(tabindex="-1") #bber-talk.swiper-wrapper(onclick=`pjax.loadUrl("/essay/")`) each i in site.data.essay each item, index in i.essay_list if index < 10 - var contentText = item.image ? item.content + ' [图片]' : item.content .li-style.swiper-slide= contentText i.bber-gotobb.fas.fa-arrow-circle-right(onclick=`pjax.loadUrl("/essay/")`,title="查看全文")
引入到主页 修改themes/butterfly/layout/index.pug
, 注意缩进
1 2 3 4 5 6 7 block content include ./includes/mixins/post-ui.pug #recent-posts.recent-posts include includes/categoryList.pug + include includes/bbTimeList.pug +postUI include includes/pagination.pug
如果需要像本站一样在整个顶部引入的话可以参考下面的代码,修改themes/butterfly/layout/includes/layout.pug
1 2 3 4 5 if page.type !== '404' #body-wrap(class=pageType) include ./header/index.pug + if (is_home()) + include ./bbTimeList.pug
引入 swiper 依赖 在_config.butterfly.yml
引入依赖, 如果有使用轮播图插件的话此处无需引入
1 2 3 4 5 inject: head: - <link rel="stylesheet" href="https://npm.elemecdn.com/hexo-butterfly-swiper-anzhiyu@1.0.4/lib/swiper.min.css"> bottom: - <script data-pjax src="https://npm.elemecdn.com/anzhiyu-blog@1.1.6/js/swiper.min.js"></script>
添加自定义 css 创建source/css/essay_page/home_essay_bar.css
, 然后在_config.butterfly.yml
中的inject
下的head
引入, 注意缩进
1 2 3 inject: head: - <link rel="stylesheet" href="/css/essay_page/home_essay_bar.css">
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 #bbTimeList { background : var (--anzhiyu-white); color : var (--anzhiyu-fontcolor); padding : 0.5rem 1rem ; border-radius : 30px ; box-shadow : var (--anzhiyu-shadow-lightblack); display : flex; transition : all 0.3s ease 0s ; margin : 1rem auto 0 ; border : var (--style-border); align-items : center; height : 50px ; width : 100% ; } [data-theme="dark" ] #bbTimeList { background : #000 !important ; } #bbtalk { width : 100% ; overflow : hidden; text-overflow : ellipsis; white-space : nowrap; } #bber-talk { width : 100% ; height : 25px ; line-height : 25px ; display : flex; flex-direction : column; } .bber-logo { font-size : 1.5rem ; line-height : 22px ; margin-right : 1rem ; transition : all 0.3s ease 0s ; cursor : pointer; } .bber-gotobb { line-height : 25px ; margin-left : 1rem ; transition : all 0.3s ease 0s ; cursor : pointer; } #bber-talk .li-style { width : 100% ; max-width : 100% ; height : 25px ; text-align : center; overflow : hidden; text-overflow : ellipsis; transition : 0.3s ; font-weight : 700 ; margin : auto; cursor : pointer; white-space : nowrap; } #bbTimeList :hover { border : var (--style-border-hover); box-shadow : var (--anzhiyu-shadow-main); } .bbTimeList .bber-logo { -webkit-animation : rotate 1.6s linear infinite; animation : rotate 1.6s linear infinite; } @-webkit-keyframes rotate { 0% { -webkit-transform : rotate (0deg ); transform : rotate (0deg ); } to { -webkit-transform : rotate (-1turn ); transform : rotate (-1turn ); } } @keyframes rotate { 0% { -webkit-transform : rotate (0deg ); transform : rotate (0deg ); } to { -webkit-transform : rotate (-1turn ); transform : rotate (-1turn ); } }
修改自定义 js 修改custom.js
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 var percentFlag = false ; function essayScroll ( ) { let a = document .documentElement .scrollTop || window .pageYOffset ; const waterfallResult = a % document .documentElement .clientHeight ; result <= 99 || (result = 99 ); if ( !percentFlag && waterfallResult + 100 >= document .documentElement .clientHeight && document .querySelector ("#waterfall" ) ) { setTimeout (() => { waterfall ("#waterfall" ); }, 500 ); } else { setTimeout (() => { document .querySelector ("#waterfall" ) && waterfall ("#waterfall" ); }, 500 ); } const r = window .scrollY + document .documentElement .clientHeight ; let p = document .getElementById ("post-comment" ) || document .getElementById ("footer" ); (p.offsetTop + p.offsetHeight / 2 < r || 90 < result) && (percentFlag = true ); } function replaceAll (e, n, t ) { return e.split (n).join (t); } var anzhiyu = { diffDate : function (d, more = false ) { const dateNow = new Date (); const datePost = new Date (d); const dateDiff = dateNow.getTime () - datePost.getTime (); const minute = 1000 * 60 ; const hour = minute * 60 ; const day = hour * 24 ; const month = day * 30 ; let result; if (more) { const monthCount = dateDiff / month; const dayCount = dateDiff / day; const hourCount = dateDiff / hour; const minuteCount = dateDiff / minute; if (monthCount >= 1 ) { result = datePost.toLocaleDateString ().replace (/\//g , "-" ); } else if (dayCount >= 1 ) { result = parseInt (dayCount) + " " + GLOBAL_CONFIG .date_suffix .day ; } else if (hourCount >= 1 ) { result = parseInt (hourCount) + " " + GLOBAL_CONFIG .date_suffix .hour ; } else if (minuteCount >= 1 ) { result = parseInt (minuteCount) + " " + GLOBAL_CONFIG .date_suffix .min ; } else { result = GLOBAL_CONFIG .date_suffix .just ; } } else { result = parseInt (dateDiff / day); } return result; }, changeTimeInEssay : function ( ) { document .querySelector ("#bber" ) && document .querySelectorAll ("#bber time" ).forEach (function (e ) { var t = e, datetime = t.getAttribute ("datetime" ); (t.innerText = anzhiyu.diffDate (datetime, true )), (t.style .display = "inline" ); }); }, reflashEssayWaterFall : function ( ) { document .querySelector ("#waterfall" ) && setTimeout (function ( ) { waterfall ("#waterfall" ); document .getElementById ("waterfall" ).classList .add ("show" ); }, 500 ); }, commentText : function (txt ) { const postCommentDom = document .querySelector ("#post-comment" ); var domTop = postCommentDom.offsetTop ; window .scrollTo (0 , domTop - 80 ); if (txt == "undefined" || txt == "null" ) txt = "好棒!" ; function setText ( ) { setTimeout (() => { var input = document .getElementsByClassName ("el-textarea__inner" )[0 ]; if (!input) setText (); let evt = document .createEvent ("HTMLEvents" ); evt.initEvent ("input" , true , true ); let inputValue = replaceAll (txt, "\n" , "\n> " ); input.value = "> " + inputValue + "\n\n" ; input.dispatchEvent (evt); input.focus (); input.setSelectionRange (-1 , -1 ); if (document .getElementById ("comment-tips" )) { document .getElementById ("comment-tips" ).classList .add ("show" ); } }, 100 ); } setText (); }, initIndexEssay : function ( ) { setTimeout (() => { let essay_bar_swiper = new Swiper (".essay_bar_swiper_container" , { passiveListeners : true , direction : "vertical" , loop : true , autoplay : { disableOnInteraction : true , delay : 3000 , }, mousewheel : true , }); let essay_bar_comtainer = document .getElementById ("bbtalk" ); if (essay_bar_comtainer !== null ) { essay_bar_comtainer.onmouseenter = function ( ) { essay_bar_swiper.autoplay .stop (); }; essay_bar_comtainer.onmouseleave = function ( ) { essay_bar_swiper.autoplay .start (); }; } }, 100 ); }, }; anzhiyu.initIndexEssay (); anzhiyu.changeTimeInEssay (); anzhiyu.reflashEssayWaterFall ();
主要是新增了在anzhiyu
变量中的initIndexEssay
方法, 该方法用于初始化 swiper 轮播。
教程就到这里啦~, 相册集也是同理所做, 可以自行魔改。