feat: add lazyload image
This commit is contained in:
parent
86f2e3ccc9
commit
3abec3cb33
|
@ -176,6 +176,13 @@ rss:
|
||||||
enable: false
|
enable: false
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------------------
|
||||||
|
# lazyload image
|
||||||
|
# ---------------------------------------------------------------------------------------
|
||||||
|
lazyload:
|
||||||
|
enable: false
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------------------
|
||||||
# CDN
|
# CDN
|
||||||
# ---------------------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
<%- __js('js/code-copy.js') %>
|
<%- __js('js/code-copy.js') %>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
|
<% if (theme.lazyload.enable) { %>
|
||||||
|
<%- __js('js/lazyload.js') %>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
<div class="post-scripts<%= theme.pjax.enable === true ? ' pjax' : '' %>">
|
<div class="post-scripts<%= theme.pjax.enable === true ? ' pjax' : '' %>">
|
||||||
<% if (theme.toc.enable && is_post()) { %>
|
<% if (theme.toc.enable && is_post()) { %>
|
||||||
<%- __js([
|
<%- __js([
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
'use strict'
|
||||||
|
hexo.extend.filter.register(
|
||||||
|
'after_post_render',
|
||||||
|
function (data) {
|
||||||
|
const theme = hexo.theme.config;
|
||||||
|
if (!theme.lazyload || !theme.lazyload.enable) return;
|
||||||
|
data.content = data.content.replace(
|
||||||
|
// Match 'img' tags width the src attribute.
|
||||||
|
/<img([^>]*)src="([^"]*)"([^>]*)>/gim,
|
||||||
|
function (match, attrBegin, src, attrEnd) {
|
||||||
|
// Exit if the src doesn't exists.
|
||||||
|
if (!src) return match;
|
||||||
|
|
||||||
|
return `<img ${attrBegin}
|
||||||
|
lazyload
|
||||||
|
src="/images/loading.svg"
|
||||||
|
data-src="${src}"
|
||||||
|
${attrEnd}
|
||||||
|
>`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
1
|
||||||
|
);
|
|
@ -14,7 +14,7 @@ hexo.extend.helper.register('export_config', function () {
|
||||||
|
|
||||||
let {config, theme} = this;
|
let {config, theme} = this;
|
||||||
|
|
||||||
// ------------ export language to js ------------
|
// ------------------------ export language to js ------------------------
|
||||||
const languageDir = path.join(__dirname, '../../languages');
|
const languageDir = path.join(__dirname, '../../languages');
|
||||||
let file = fs.readdirSync(languageDir).find(v => v === `${config.language}.yml`);
|
let file = fs.readdirSync(languageDir).find(v => v === `${config.language}.yml`);
|
||||||
file = languageDir + '/' + (file ? file : 'en.yml');
|
file = languageDir + '/' + (file ? file : 'en.yml');
|
||||||
|
@ -24,7 +24,7 @@ hexo.extend.helper.register('export_config', function () {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
let hexo_config = {
|
let hexo_config = {
|
||||||
|
@ -43,6 +43,7 @@ hexo.extend.helper.register('export_config', function () {
|
||||||
code_copy: theme.code_copy,
|
code_copy: theme.code_copy,
|
||||||
side_tools: theme.side_tools,
|
side_tools: theme.side_tools,
|
||||||
pjax: theme.pjax,
|
pjax: theme.pjax,
|
||||||
|
lazyload: theme.lazyload,
|
||||||
version: theme.version,
|
version: theme.version,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
@require 'keep-theme.styl'
|
@require 'keep-theme.styl'
|
||||||
|
|
||||||
|
|
||||||
// ============================
|
// ======================================================================
|
||||||
// html, body
|
// html, body
|
||||||
// ============================
|
// ======================================================================
|
||||||
html, body {
|
html, body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -29,9 +29,9 @@ html, body {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================
|
// ======================================================================
|
||||||
// scrollbar
|
// scrollbar
|
||||||
// ============================
|
// ======================================================================
|
||||||
* {
|
* {
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
width: 6px;
|
width: 6px;
|
||||||
|
@ -48,18 +48,18 @@ html, body {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================
|
// ======================================================================
|
||||||
// selection
|
// selection
|
||||||
// ============================
|
// ======================================================================
|
||||||
::selection {
|
::selection {
|
||||||
background: var(--selection-color);
|
background: var(--selection-color);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================
|
// ======================================================================
|
||||||
// ul, ol, li
|
// ul, ol, li
|
||||||
// ============================
|
// ======================================================================
|
||||||
ul, ol, li {
|
ul, ol, li {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -67,9 +67,9 @@ ul, ol, li {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================
|
// ======================================================================
|
||||||
// a
|
// a
|
||||||
// ============================
|
// ======================================================================
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: var(--default-text-color);
|
color: var(--default-text-color);
|
||||||
|
@ -82,9 +82,24 @@ a {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================
|
// ======================================================================
|
||||||
|
// img
|
||||||
|
// ======================================================================
|
||||||
|
img {
|
||||||
|
&[lazyload] {
|
||||||
|
padding: 20px;
|
||||||
|
cursor: not-allowed;
|
||||||
|
pointer-events: none;
|
||||||
|
margin: 20px auto !important;
|
||||||
|
background: var(--lazyload-background-color);
|
||||||
|
transition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
// button
|
// button
|
||||||
// ============================
|
// ======================================================================
|
||||||
button {
|
button {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -113,9 +128,9 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================
|
// ======================================================================
|
||||||
// flex center
|
// flex center
|
||||||
// ============================
|
// ======================================================================
|
||||||
.flex-center {
|
.flex-center {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -123,9 +138,9 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================
|
// ======================================================================
|
||||||
// clear float
|
// clear float
|
||||||
// ============================
|
// ======================================================================
|
||||||
.clear {
|
.clear {
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,6 +172,7 @@
|
||||||
cursor: zoom-in;
|
cursor: zoom-in;
|
||||||
display: block;
|
display: block;
|
||||||
box-shadow: 0 0 2px var(--shadow-color);
|
box-shadow: 0 0 2px var(--shadow-color);
|
||||||
|
transition();
|
||||||
|
|
||||||
if (hexo-config('style.article_img_align') == 'center') {
|
if (hexo-config('style.article_img_align') == 'center') {
|
||||||
margin: 10px auto 2px;
|
margin: 10px auto 2px;
|
||||||
|
|
|
@ -6,24 +6,25 @@
|
||||||
// ========================================================================================
|
// ========================================================================================
|
||||||
// layout
|
// layout
|
||||||
// ========================================================================================
|
// ========================================================================================
|
||||||
$header-height = 76px; // 头部默认高度
|
$header-height = 76px; // header height
|
||||||
$header-shrink-height = $header-height * 0.72; // 头部收缩高度
|
$header-shrink-height = $header-height * 0.72; // header shrink height
|
||||||
$scroll-progress-bar-height = 2px; // 头部进度条高度
|
$scroll-progress-bar-height = 2px; // scroll progress bar height
|
||||||
$main-content-width = 80%; // 中间内容区域宽度(PC)
|
$main-content-width = 80%; // main content width (tablet)
|
||||||
$main-content-width-tablet = 85%; // 中间内容区域宽度(平板)
|
$main-content-width-tablet = 86%; // main content width (PC)
|
||||||
$main-content-width-mobile = 90%; // 中间内容区域宽度(手机)
|
$main-content-width-mobile = 90%; // main content width (mobile)
|
||||||
$circle-button-width = 40px; // tools 圆形工具按钮宽度
|
$circle-button-width = 38px; // post tool button width
|
||||||
$tools-button-width = 32px; // tools 方形工具按钮宽度
|
$component-spacing-value = 30px; // component-spacing-value (PC)
|
||||||
$component-interspace = 30px; // 组件/模块的间隔值(PC)
|
|
||||||
|
// main content max width
|
||||||
$temp-content-max-width = hexo-config('style.content_max_width');
|
$temp-content-max-width = hexo-config('style.content_max_width');
|
||||||
$content-max-width = $temp-content-max-width ? convert($temp-content-max-width) : 1000px;
|
$content-max-width = $temp-content-max-width ? convert($temp-content-max-width) : 1000px;
|
||||||
|
|
||||||
|
|
||||||
// ========================================================================================
|
// ========================================================================================
|
||||||
// 媒体查询
|
// media query
|
||||||
// ========================================================================================
|
// ========================================================================================
|
||||||
$media-max-width = 780px; // 媒体查询最大宽度 (平板)
|
$media-max-width = 780px; // media query max width (tablet)
|
||||||
$media-max-width-mobile = 500px; // 媒体查询最大宽度(手机)
|
$media-max-width-mobile = 500px; // media query max width (mobile)
|
||||||
|
|
||||||
keep-tablet()
|
keep-tablet()
|
||||||
@media (max-width: $media-max-width)
|
@media (max-width: $media-max-width)
|
||||||
|
@ -76,6 +77,7 @@ $link-color = darken($default-text-color, 10%);
|
||||||
$copyright-info-color = #CC0033;
|
$copyright-info-color = #CC0033;
|
||||||
$avatar-background-color = #0066CC;
|
$avatar-background-color = #0066CC;
|
||||||
$loading-progress-bar-color = #990000;
|
$loading-progress-bar-color = #990000;
|
||||||
|
$lazyload-background-color = rgba(200, 200, 200, 0.5);
|
||||||
|
|
||||||
|
|
||||||
// ========================================================================================
|
// ========================================================================================
|
||||||
|
@ -99,6 +101,7 @@ $dark-link-color = lighten($dark-default-text-color, 10%);
|
||||||
$dark-copyright-info-color = darken($copyright-info-color, 20%);
|
$dark-copyright-info-color = darken($copyright-info-color, 20%);
|
||||||
$dark-avatar-background-color = darken($avatar-background-color, 10%);
|
$dark-avatar-background-color = darken($avatar-background-color, 10%);
|
||||||
$dark-loading-progress-bar-color = lighten($loading-progress-bar-color, 50%);
|
$dark-loading-progress-bar-color = lighten($loading-progress-bar-color, 50%);
|
||||||
|
$dark-lazyload-background-color = rgba(50, 50, 50, 0.5);
|
||||||
|
|
||||||
|
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
@ -131,7 +134,8 @@ root-color(mode) {
|
||||||
--link-color: mode == 'light' ? $link-color : $dark-link-color;
|
--link-color: mode == 'light' ? $link-color : $dark-link-color;
|
||||||
--copyright-info-color: mode == 'light' ? $copyright-info-color : $dark-copyright-info-color;
|
--copyright-info-color: mode == 'light' ? $copyright-info-color : $dark-copyright-info-color;
|
||||||
--avatar-background-color: mode == 'light' ? $avatar-background-color : $dark-avatar-background-color;
|
--avatar-background-color: mode == 'light' ? $avatar-background-color : $dark-avatar-background-color;
|
||||||
--loading-progress-bar-color: mode == 'light' ? $loading-progress-bar-color : $dark-loading-progress-bar-color;
|
--loading-progress-bar-color : mode == 'light' ? $loading-progress-bar-color : $dark-loading-progress-bar-color;
|
||||||
|
--lazyload-background-color : mode == 'light' ? $lazyload-background-color : $dark-lazyload-background-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ $article-date-font-size = 1rem;
|
||||||
.archive-list-container {
|
.archive-list-container {
|
||||||
|
|
||||||
.archive-item {
|
.archive-item {
|
||||||
margin-bottom: $component-interspace;
|
margin-bottom: $component-spacing-value;
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|
|
@ -12,7 +12,7 @@ if (hexo-config('comment.valine.enable') && hexo-config('comment.gitalk.enable')
|
||||||
|
|
||||||
.comments-container {
|
.comments-container {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-top: $component-interspace;
|
margin-top: $component-spacing-value;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
#comment-anchor {
|
#comment-anchor {
|
||||||
|
|
|
@ -91,7 +91,7 @@ $article-title-font-size = 1.6rem;
|
||||||
|
|
||||||
|
|
||||||
.article-content {
|
.article-content {
|
||||||
margin-top: $component-interspace;
|
margin-top: $component-spacing-value;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
@ -99,13 +99,13 @@ $article-title-font-size = 1.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-copyright-info {
|
.post-copyright-info {
|
||||||
margin-top: $component-interspace;
|
margin-top: $component-spacing-value;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-nav {
|
.article-nav {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
margin-top: $component-interspace;
|
margin-top: $component-spacing-value;
|
||||||
|
|
||||||
.article-prev, .article-next {
|
.article-prev, .article-next {
|
||||||
max-width: $post-nav-max-width;
|
max-width: $post-nav-max-width;
|
||||||
|
|
|
@ -18,7 +18,7 @@ $category-name-font-size = 1.6rem;
|
||||||
|
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
margin-bottom: $component-interspace;
|
margin-bottom: $component-spacing-value;
|
||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,14 +78,14 @@ $page-aside-width = $temp-width ? convert($temp-width) : 260px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: $component-interspace 0;
|
padding: $component-spacing-value 0;
|
||||||
|
|
||||||
+keep-tablet() {
|
+keep-tablet() {
|
||||||
padding: $component-interspace * 0.8 0;
|
padding: $component-spacing-value * 0.8 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
+keep-mobile() {
|
+keep-mobile() {
|
||||||
padding: $component-interspace * 0.6 0;
|
padding: $component-spacing-value * 0.6 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
|
@ -137,25 +137,25 @@ $page-aside-width = $temp-width ? convert($temp-width) : 260px;
|
||||||
|
|
||||||
.post-tools {
|
.post-tools {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: $header-height + $component-interspace;
|
top: $header-height + $component-spacing-value;
|
||||||
right: $component-interspace;
|
right: $component-spacing-value;
|
||||||
transition();
|
transition();
|
||||||
|
|
||||||
.header-shrink & {
|
.header-shrink & {
|
||||||
top: $header-shrink-height + $component-interspace;
|
top: $header-shrink-height + $component-spacing-value;
|
||||||
|
|
||||||
+keep-tablet() {
|
+keep-tablet() {
|
||||||
top: $header-shrink-height * 0.9 + $component-interspace;
|
top: $header-shrink-height * 0.9 + $component-spacing-value;
|
||||||
}
|
}
|
||||||
|
|
||||||
+keep-mobile() {
|
+keep-mobile() {
|
||||||
top: $header-shrink-height * 0.8 + $component-interspace;
|
top: $header-shrink-height * 0.8 + $component-spacing-value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
+keep-tablet() {
|
+keep-tablet() {
|
||||||
top: $header-height * 0.9 + $component-interspace;
|
top: $header-height * 0.9 + $component-spacing-value;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
transform: scale(0.82);
|
transform: scale(0.82);
|
||||||
transform-origin: right top;
|
transform-origin: right top;
|
||||||
|
@ -163,7 +163,7 @@ $page-aside-width = $temp-width ? convert($temp-width) : 260px;
|
||||||
|
|
||||||
|
|
||||||
+keep-mobile() {
|
+keep-mobile() {
|
||||||
top: $header-height * 0.8 + $component-interspace;
|
top: $header-height * 0.8 + $component-spacing-value;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
transform: scale(0.72);
|
transform: scale(0.72);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ $tag-name-font-size = 1.6rem;
|
||||||
|
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
margin-bottom: $component-interspace;
|
margin-bottom: $component-spacing-value;
|
||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<!-- By Sam Herbert (@sherb), for everyone. More @ http://goo.gl/7AJzbL -->
|
||||||
|
<svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" stroke="#fff">
|
||||||
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<g transform="translate(1 1)" stroke-width="2">
|
||||||
|
<circle stroke-opacity=".5" cx="18" cy="18" r="18"/>
|
||||||
|
<path d="M36 18c0-9.94-8.06-18-18-18">
|
||||||
|
<animateTransform
|
||||||
|
attributeName="transform"
|
||||||
|
type="rotate"
|
||||||
|
from="0 18 18"
|
||||||
|
to="360 18 18"
|
||||||
|
dur="1s"
|
||||||
|
repeatCount="indefinite"/>
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 694 B |
|
@ -0,0 +1,41 @@
|
||||||
|
KEEP.initLazyLoad = () => {
|
||||||
|
const imgs = document.querySelectorAll('img');
|
||||||
|
let now = Date.now();
|
||||||
|
let needLoad = true;
|
||||||
|
|
||||||
|
function lazyload(imgs) {
|
||||||
|
now = Date.now();
|
||||||
|
needLoad = Array.from(imgs).some(i => i.hasAttribute('lazyload'));
|
||||||
|
|
||||||
|
const h = window.innerHeight;
|
||||||
|
const s = document.documentElement.scrollTop || document.body.scrollTop;
|
||||||
|
|
||||||
|
imgs.forEach(img => {
|
||||||
|
if (img.hasAttribute('lazyload') && !img.hasAttribute('loading')) {
|
||||||
|
|
||||||
|
if ((h + s) > img.offsetTop) {
|
||||||
|
img.setAttribute('loading', true);
|
||||||
|
const loadImageTimeout = setTimeout(() => {
|
||||||
|
const temp = new Image();
|
||||||
|
const src = img.getAttribute('data-src');
|
||||||
|
temp.src = src;
|
||||||
|
temp.onload = () => {
|
||||||
|
img.src = src;
|
||||||
|
img.removeAttribute('lazyload');
|
||||||
|
img.removeAttribute('loading');
|
||||||
|
clearTimeout(loadImageTimeout);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
lazyload(imgs);
|
||||||
|
|
||||||
|
window.onscroll = () => {
|
||||||
|
if (Date.now() - now > 100 && needLoad) {
|
||||||
|
lazyload(imgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,10 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||||
if (KEEP.theme_config.code_copy.enable === true) {
|
if (KEEP.theme_config.code_copy.enable === true) {
|
||||||
KEEP.initCodeCopy();
|
KEEP.initCodeCopy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (KEEP.theme_config.lazyload.enable === true) {
|
||||||
|
KEEP.initLazyLoad();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KEEP.refresh();
|
KEEP.refresh();
|
||||||
|
|
Loading…
Reference in New Issue