diff --git a/_config.yml b/_config.yml index fb4c7cb..1f880ac 100755 --- a/_config.yml +++ b/_config.yml @@ -147,7 +147,7 @@ plugins: # image lazyload # https://www.npmjs.com/package/vanilla-lazyload lazyload: - enable: true + enable: true # [hexo clean && hexo s] is required after changing this value. js: https://cdn.jsdelivr.net/npm/vanilla-lazyload@17.3.1/dist/lazyload.min.js onlypost: false loadingImg: # https://7.dusays.com/2021/02/14/e45d2469cdeaf.svg diff --git a/languages/en.yml b/languages/en.yml index 3934dc6..e71d45c 100755 --- a/languages/en.yml +++ b/languages/en.yml @@ -22,6 +22,14 @@ meta: comment_title: Join the discussion back_to_top: Back to top more: 'More %s' + created: 'Posted on' + updated: 'Updated on' + date_suffix: + just: Just + min: minutes ago + hour: hours ago + day: days ago + month: months ago footer: license: 'All articles in this blog are licensed under %s unless stating additionally.' diff --git a/languages/zh-CN.yml b/languages/zh-CN.yml index 1a5c950..d51a269 100755 --- a/languages/zh-CN.yml +++ b/languages/zh-CN.yml @@ -22,6 +22,14 @@ meta: comment_title: 快来参与讨论吧 back_to_top: 回到顶部 more: '更多%s' + created: 发布于 + updated: 更新于 + date_suffix: + just: 刚刚 + min: 分钟前 + hour: 小时前 + day: 天前 + month: 个月前 footer: license: '本博客所有文章除特别声明外,均采用 %s 许可协议。转载请注明出处!' diff --git a/languages/zh-TW.yml b/languages/zh-TW.yml index bfef025..8f6382f 100755 --- a/languages/zh-TW.yml +++ b/languages/zh-TW.yml @@ -22,6 +22,14 @@ meta: comment_title: 快來參與討論吧 back_to_top: 回到頂部 more: '更多%s' + created: 發表於 + updated: 更新於 + date_suffix: + just: 剛剛 + min: 分鐘前 + hour: 小時前 + day: 天前 + month: 個月前 footer: license: '本網誌所有文章除特別聲明外,均採用 %s 許可協議。轉載請註明出處!' diff --git a/layout/_partial/main/navbar/breadcrumb.ejs b/layout/_partial/main/navbar/breadcrumb.ejs index 7e9be7a..0bf0522 100644 --- a/layout/_partial/main/navbar/breadcrumb.ejs +++ b/layout/_partial/main/navbar/breadcrumb.ejs @@ -15,8 +15,8 @@ }) %> <% } %> -
- +
+ <%- __('meta.created') %> 
<% } else if (page.layout == 'wiki') { %>
@@ -36,6 +36,9 @@ <%- page.wiki %> <% }); %>
+
+ <%- __('meta.updated') %>  +
<% } else { %>
<%- __('btn.home') %> diff --git a/layout/_partial/main/post_list/post_card.ejs b/layout/_partial/main/post_list/post_card.ejs index 7761503..37642ac 100755 --- a/layout/_partial/main/post_list/post_card.ejs +++ b/layout/_partial/main/post_list/post_card.ejs @@ -30,8 +30,8 @@ if (post.categories && post.categories.length > 0) { <% } %>
- - + + <%- __('meta.created') %>  <% if (showCat) { %> <% if (post.layout == 'post' && post.categories && post.categories.length > 0) { %> diff --git a/layout/_partial/menubtn.ejs b/layout/_partial/menubtn.ejs index dff7a33..bcaee67 100644 --- a/layout/_partial/menubtn.ejs +++ b/layout/_partial/menubtn.ejs @@ -1,5 +1,5 @@ diff --git a/layout/_partial/scripts/index.ejs b/layout/_partial/scripts/index.ejs index f240f73..5c82982 100644 --- a/layout/_partial/scripts/index.ejs +++ b/layout/_partial/scripts/index.ejs @@ -1,21 +1,44 @@ + + -<%- js({src: theme.plugins.jquery || 'https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js'}) %> <% if (theme.stellar.cdn_js) { %> <%- js({src: theme.stellar.cdn_js, async: true}) %> <% } else { %> - <%- js({src: 'js/main.js', async: true}) %> + <%- js({src: '/js/main.js', async: true}) %> <% } %> - - -<%- partial('lazyload') %> -<%- partial('preload') %> -<%- partial('swiper') %> - -<%- partial('scrollreveal') %> - - <%- partial('../plugins/comments/script') %> @@ -24,7 +47,3 @@ <%- js %> <% }) %> <% } %> - - - -<%- partial('issues') %> diff --git a/layout/_partial/scripts/issues.ejs b/layout/_partial/scripts/issues.ejs deleted file mode 100644 index 567cc1b..0000000 --- a/layout/_partial/scripts/issues.ejs +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/layout/_partial/scripts/lazyload.ejs b/layout/_partial/scripts/lazyload.ejs deleted file mode 100644 index 48bd52a..0000000 --- a/layout/_partial/scripts/lazyload.ejs +++ /dev/null @@ -1,25 +0,0 @@ -<% if (theme.plugins.lazyload && theme.plugins.lazyload.enable) { %> - - - -<% } %> diff --git a/layout/_partial/scripts/preload.ejs b/layout/_partial/scripts/preload.ejs deleted file mode 100644 index 5db5783..0000000 --- a/layout/_partial/scripts/preload.ejs +++ /dev/null @@ -1,16 +0,0 @@ -<% if (theme.plugins.preload.enable && theme.plugins.preload.service) { %> - <% let preload = theme.plugins.preload; %> - <% if (preload.service == 'instant_page') { %> - - <% } else if (preload.service == 'flying_pages') { %> - - - <% } %> -<% } %> diff --git a/layout/_partial/scripts/scrollreveal.ejs b/layout/_partial/scripts/scrollreveal.ejs deleted file mode 100644 index 6760c34..0000000 --- a/layout/_partial/scripts/scrollreveal.ejs +++ /dev/null @@ -1,12 +0,0 @@ -<% if (theme.plugins.scrollreveal.enable && theme.plugins.scrollreveal.js) { %> - <%- js(theme.plugins.scrollreveal.js) %> - -<% } %> diff --git a/layout/_partial/scripts/swiper.ejs b/layout/_partial/scripts/swiper.ejs deleted file mode 100644 index e9a2504..0000000 --- a/layout/_partial/scripts/swiper.ejs +++ /dev/null @@ -1,29 +0,0 @@ - diff --git a/scripts/tags/swiper.js b/scripts/tags/swiper.js index 97b98f5..f9317b5 100644 --- a/scripts/tags/swiper.js +++ b/scripts/tags/swiper.js @@ -1,7 +1,7 @@ /** * swiper.js v1 | https://github.com/xaoxuu/hexo-theme-stellar/ * 格式与官方标签插件一致使用空格分隔,中括号内的是可选参数(中括号不需要写出来) - * + * * {% swiper %} * ![img](src) * {% endswiper %} @@ -23,7 +23,7 @@ hexo.extend.tag.register('swiper', function(args, content) { }); } } - el += '
0) { el += ' ' + ArgsJoinTags(args, 'width').join(' '); } diff --git a/source/css/_layout/base.styl b/source/css/_layout/base.styl index 1351a7f..a586290 100644 --- a/source/css/_layout/base.styl +++ b/source/css/_layout/base.styl @@ -66,6 +66,8 @@ span.dot:before content: '·' span.sep:before content: '/' + padding-left: 2px + padding-right: 2px hr color: var(--text-meta) diff --git a/source/js/main.js b/source/js/main.js index 4d8e097..df1fcb8 100644 --- a/source/js/main.js +++ b/source/js/main.js @@ -1,127 +1,300 @@ -const l_body = document.querySelector('.l_body'); +// utils +const util = { -// 懒加载 js -function loadScript(src, cb) { - setTimeout(function () { - var HEAD = - document.getElementsByTagName("head")[0] || document.documentElement; - var script = document.createElement("script"); - script.setAttribute("type", "text/javascript"); - if (cb) script.onload = cb; - script.setAttribute("src", src); - HEAD.appendChild(script); - }); -} -// 懒加载 css https://github.com/filamentgroup/loadCSS -var loadCSS = function (href, before, media, attributes) { - var doc = window.document; - var ss = doc.createElement("link"); - var ref; - if (before) { - ref = before; - } else { - var refs = (doc.body || doc.getElementsByTagName("head")[0]).childNodes; - ref = refs[refs.length - 1]; - } - var sheets = doc.styleSheets; - if (attributes) { - for (var attributeName in attributes) { - if (attributes.hasOwnProperty(attributeName)) { - ss.setAttribute(attributeName, attributes[attributeName]); + // https://github.com/jerryc127/hexo-theme-butterfly + diffDate: (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 > 12) { + result = null + } else if (monthCount >= 1) { + result = parseInt(monthCount) + ' ' + stellar.config.date_suffix.month + } else if (dayCount >= 1) { + result = parseInt(dayCount) + ' ' + stellar.config.date_suffix.day + } else if (hourCount >= 1) { + result = parseInt(hourCount) + ' ' + stellar.config.date_suffix.hour + } else if (minuteCount >= 1) { + result = parseInt(minuteCount) + ' ' + stellar.config.date_suffix.min + } else { + result = stellar.config.date_suffix.just + } + } else { + result = parseInt(dateDiff / day) + } + return result + }, + + // 懒加载 css https://github.com/filamentgroup/loadCSS + loadCSS: (href, before, media, attributes) => { + var doc = window.document; + var ss = doc.createElement("link"); + var ref; + if (before) { + ref = before; + } else { + var refs = (doc.body || doc.getElementsByTagName("head")[0]).childNodes; + ref = refs[refs.length - 1]; + } + var sheets = doc.styleSheets; + if (attributes) { + for (var attributeName in attributes) { + if (attributes.hasOwnProperty(attributeName)) { + ss.setAttribute(attributeName, attributes[attributeName]); + } } } - } - ss.rel = "stylesheet"; - ss.href = href; - ss.media = "only x"; - function ready(cb) { - if (doc.body) { - return cb(); - } - setTimeout(function () { - ready(cb); - }); - } - ready(function () { - ref.parentNode.insertBefore(ss, before ? ref : ref.nextSibling); - }); - var onloadcssdefined = function (cb) { - var resolvedHref = ss.href; - var i = sheets.length; - while (i--) { - if (sheets[i].href === resolvedHref) { + ss.rel = "stylesheet"; + ss.href = href; + ss.media = "only x"; + function ready(cb) { + if (doc.body) { return cb(); } + setTimeout(function () { + ready(cb); + }); } - setTimeout(function () { - onloadcssdefined(cb); + ready(function () { + ref.parentNode.insertBefore(ss, before ? ref : ref.nextSibling); }); - }; - function loadCB() { + var onloadcssdefined = function (cb) { + var resolvedHref = ss.href; + var i = sheets.length; + while (i--) { + if (sheets[i].href === resolvedHref) { + return cb(); + } + } + setTimeout(function () { + onloadcssdefined(cb); + }); + }; + function loadCB() { + if (ss.addEventListener) { + ss.removeEventListener("load", loadCB); + } + ss.media = media || "all"; + } if (ss.addEventListener) { - ss.removeEventListener("load", loadCB); + ss.addEventListener("load", loadCB); + } + ss.onloadcssdefined = onloadcssdefined; + onloadcssdefined(loadCB); + return ss; + }, + + // 从 butterfly 和 volantis 获得灵感 + loadScript: (src, opt) => new Promise((resolve, reject) => { + const script = document.createElement('script') + script.src = src + if (opt) { + for (let key of Object.keys(opt)) { + script[key] = opt[key] + } + } else { + // 默认异步,如果需要同步,第二个参数传入 {} 即可 + script.async = true + } + script.onerror = reject + script.onload = script.onreadystatechange = function() { + const loadState = this.readyState + if (loadState && loadState !== 'loaded' && loadState !== 'complete') return + script.onload = script.onreadystatechange = null + resolve() + } + document.head.appendChild(script) + }), + + // https://github.com/jerryc127/hexo-theme-butterfly + jQuery: (fn) => { + if (typeof jQuery === 'undefined') { + util.loadScript(stellar.plugins.jQuery).then(fn) + } else { + fn() + } + }, + +} + + +// defines + +const l_body = document.querySelector('.l_body'); + +const sidebar = { + toggle: () => { + if (l_body) { + l_body.classList.add('mobile'); + l_body.classList.toggle("sidebar"); } - ss.media = media || "all"; - } - if (ss.addEventListener) { - ss.addEventListener("load", loadCB); - } - ss.onloadcssdefined = onloadcssdefined; - onloadcssdefined(loadCB); - return ss; -}; -// 弹出侧边栏 -function toggleSidebar() { - if (l_body) { - l_body.classList.add('mobile'); - l_body.classList.toggle("sidebar"); } } -function setToc() { - const scrollOffset = 32; - var segs = []; - $("article.md :header").each(function (idx, node) { - segs.push(node) - }); - // 滚动 - $(document, window).scroll(function(e) { - var scrollTop = $(this).scrollTop(); - var topSeg = null - for (var idx in segs) { - var seg = $(segs[idx]) - if (seg.offset().top > scrollTop + scrollOffset) { - continue +const init = { + toc: () => { + util.jQuery(() => { + const scrollOffset = 32; + var segs = []; + $("article.md :header").each(function (idx, node) { + segs.push(node) + }); + // 滚动 + $(document, window).scroll(function(e) { + var scrollTop = $(this).scrollTop(); + var topSeg = null + for (var idx in segs) { + var seg = $(segs[idx]) + if (seg.offset().top > scrollTop + scrollOffset) { + continue + } + if (!topSeg) { + topSeg = seg + } else if (seg.offset().top >= topSeg.offset().top) { + topSeg = seg + } + } + if (topSeg) { + $("#toc a.toc-link").removeClass("active") + var link = "#" + topSeg.attr("id") + if (link != '#undefined') { + $('#toc a.toc-link[href="' + encodeURI(link) + '"]').addClass("active") + } else { + $('#toc a.toc-link:first').addClass("active") + } + } + }) + }) + }, + sidebar: () => { + util.jQuery(() => { + $("#toc a.toc-link").click(function(e) { + l_body.classList.remove("sidebar"); + }); + $("#toc a#s-top").click(function(e) { + l_body.classList.remove("sidebar"); + }); + }) + }, + relativeDate: (selector) => { + selector.forEach(item => { + const $this = item + const timeVal = $this.getAttribute('datetime') + let relativeValue = util.diffDate(timeVal, true) + if (relativeValue) { + $this.innerText = relativeValue } - if (!topSeg) { - topSeg = seg - } else if (seg.offset().top >= topSeg.offset().top) { - topSeg = seg - } - } - if (topSeg) { - $("#toc a.toc-link").removeClass("active") - var link = "#" + topSeg.attr("id") - if (link != '#undefined') { - $('#toc a.toc-link[href="' + encodeURI(link) + '"]').addClass("active") - } else { - $('#toc a.toc-link:first').addClass("active") - } - } + }) + } +} + + +// init +init.toc() +init.sidebar() +init.relativeDate(document.querySelectorAll('#post-meta time')) + + +// scrollreveal +if (stellar.plugins.scrollreveal) { + util.loadScript(stellar.plugins.scrollreveal.js).then(function () { + ScrollReveal().reveal("body .reveal", { + distance: stellar.plugins.scrollreveal.distance, + duration: stellar.plugins.scrollreveal.duration, + interval: stellar.plugins.scrollreveal.interval, + scale: stellar.plugins.scrollreveal.scale, + easing: "ease-out", + }); + }) +} + +// lazyload +if (stellar.plugins.lazyload) { + util.loadScript(stellar.plugins.lazyload.js, {defer:true}) + // https://www.npmjs.com/package/vanilla-lazyload + // Set the options globally + // to make LazyLoad self-initialize + window.lazyLoadOptions = { + elements_selector: ".lazyload", + threshold: 0 + }; + // Listen to the initialization event + // and get the instance of LazyLoad + window.addEventListener( + "LazyLoad::Initialized", + function (event) { + window.lazyLoadInstance = event.detail.instance; + }, + false + ); + document.addEventListener('DOMContentLoaded', function () { + lazyLoadInstance.update(); }); } -function setSedebar() { - $("#toc a.toc-link").click(function(e) { - l_body.classList.remove("sidebar"); - }); - $("#toc a#s-top").click(function(e) { - l_body.classList.remove("sidebar"); - }); +// issuesjs +if (stellar.plugins.issuesjs) { + const issues_api = document.getElementById('issues-api'); + if (issues_api != undefined) { + util.loadScript(stellar.plugins.issuesjs, {defer:true}) + } } -$(function () { - setToc(); - setSedebar(); -}); +// swiper +if (stellar.plugins.swiper) { + const swiper_api = document.getElementById('swiper-api'); + if (swiper_api != undefined) { + util.loadCSS(stellar.plugins.swiper.css); + util.loadScript(stellar.plugins.swiper.js, {defer:true}).then(function () { + var swiper = new Swiper('.swiper-container', { + slidesPerView: 'auto', + spaceBetween: 8, + centeredSlides: true, + zoom: true, + pagination: { + el: '.swiper-pagination', + clickable: true, + }, + autoplay: { + delay: 5000, + disableOnInteraction: false, + }, + navigation: { + nextEl: '.swiper-button-next', + prevEl: '.swiper-button-prev', + }, + }); + }) + } +} +// preload +if (stellar.plugins.preload) { + if (stellar.plugins.preload.service == 'instant_page') { + util.loadScript(stellar.plugins.preload.instant_page, { + defer:true, + type:'module', + integrity: 'sha384-OeDn4XE77tdHo8pGtE1apMPmAipjoxUQ++eeJa6EtJCfHlvijigWiJpD7VDPWXV1' + }) + } else if (stellar.plugins.preload.service == 'flying_pages') { + window.FPConfig = { + delay: 0, + ignoreKeywords: [], + maxRPS: 5, + hoverDelay: 25 + }; + util.loadScript(stellar.plugins.preload.flying_pages, {defer:true}) + } +}