UNPKG

hexo-lazyload-element

Version:

Lazyload plugin for elements like img, video and iframe.

192 lines (186 loc) 5.3 kB
const fs = require("hexo-fs"); const UglifyJS = require("uglify-js"); const lazyLoadPath = __dirname + "/client.js"; module.exports.injectScript = function (htmlContent) { const loadingImage = this.config.lazyload.loadingImg || "https://i.loli.wiki/public/240207/loading.svg"; const errorTipImage = this.config.lazyload.errorTipImage || "https://i.loli.wiki/public/240201/error-tip.svg"; const intersectionRatio = this.config.lazyload.intersectionRatio || 0.25; const placeholderRatio = this.config.lazyload.placeholderRatio || 3 / 2; const showTransition = this.config.lazyload.showTransition !== undefined ? this.config.lazyload.showTransition : true; const placeholderImage = /http/.test(loadingImage) ? `url(${loadingImage})` : loadingImage; const injectedStyles = `.lazyload-outer-wrap .caption{ width: 100%; text-align: center; display: block; } .lazyload-outer-wrap{ display: block; margin-top: 1em; margin-bottom: 1em; } .lazyload-wrap { position: relative; display: block; border-radius: 0.1em; } .lazyload-wrap .placeholder { width: 100%; height: 0; display: block; padding-bottom: ${(100 / Number(placeholderRatio)).toFixed(5)}%; background-size: 100% 100%; background-repeat: no-repeat; ${loadingImage ? `background-image: ${placeholderImage};` : ""} } .lazyload-wrap .placeholder canvas{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .lazyload-wrap .inner-wrap video, .lazyload-wrap .inner-wrap iframe{ width: 100%; height: 100%; border-radius: inherit; } .lazyload-wrap .inner-wrap, .lazyload-wrap .error-wrap{ opacity: 0; ${showTransition ? "transition: opacity ease-in-out 0.3s;" : ""} position: absolute; width: 100%; height: 100%; top: 0; left: 0; will-change: opacity; border-radius: inherit; } .lazyload-wrap .gallery-item{ border-radius: inherit; } .lazyload-wrap .inner-wrap.loaded{ opacity: 1; } .lazyload-wrap img{ object-fit: contain; display: block; margin: 0 auto !important; height: 100% !important; border-radius: inherit; } .lazyload-wrap .placeholder.loaded { background-image: none !important; background-color: unset !important; } .lazyload-wrap.loaded .inner-wrap { opacity: 1; } .lazyload-wrap .error-wrap{ background-color: #f5f5f5; opacity: 1; display: flex; flex-direction: column; justify-content: center; align-items: center; } .lazyload-wrap .error-wrap .error-tip{ width: 60%; background-size: cover; background-image: url(${errorTipImage}); } .lazyload-wrap .error-wrap .error-tip::before{ content: ''; display: block; width: 100%; padding-top: 26.79640719%; } .lazyload-wrap .error-wrap .retry-btn{ margin-top: 2em; background-image: linear-gradient(#f7f8fa ,#e7e9ec); border-color: #adb1b8 #a2a6ac #8d9096; border-style: solid; border-width: 1px; border-radius: 3px; box-shadow: rgba(255,255,255,.6) 0 1px 0 inset; box-sizing: border-box; color: #0f1111; display: inline-block; font-family: "Amazon Ember",Arial,sans-serif; font-size: 14px; height: 29px; font-size: 13px; outline: 0; overflow: hidden; padding: 0 11px; text-align: center; }`; let settingsContent = ` <script> var $lazyload = { intersectionRatio: ${intersectionRatio} } </script> `; const injectExtraScript = function (filePath) { if (!fs.exists(filePath)) throw new TypeError(filePath + " not found!"); const sourceCode = fs.readFileSync(filePath, { escape: true }); return "<script>" + UglifyJS.minify(sourceCode).code + "</script>"; }; const appendToHead = function (content, htmlContent) { const lastIndex = htmlContent.lastIndexOf("</head>"); return ( htmlContent.substring(0, lastIndex) + content + htmlContent.substring(lastIndex, htmlContent.length) ); }; const appendScript = function (content, htmlContent) { const lastIndex = htmlContent.lastIndexOf("</body>"); return ( htmlContent.substring(0, lastIndex) + content + htmlContent.substring(lastIndex, htmlContent.length) ); }; const appendToBody = function (content, htmlContent) { const lastIndex = htmlContent.indexOf("<div"); return ( htmlContent.substring(0, lastIndex) + content + htmlContent.substring(lastIndex, htmlContent.length) ); }; if (/<\/body>/gi.test(htmlContent)) { htmlContent = appendToHead( "<style>" + injectedStyles + "</style>", htmlContent ); htmlContent = appendToHead( settingsContent, htmlContent ); htmlContent = appendToHead( `<link rel="preload" as="image" href="${loadingImage}" />`, htmlContent ); htmlContent = appendToHead( `<link rel="preload" as="image" href="${errorTipImage}" />`, htmlContent ); htmlContent = appendScript(injectExtraScript(lazyLoadPath), htmlContent); htmlContent = appendToBody( "<noscript><style>.lazyload-wrap {display: none;}</style></noscript>", htmlContent ); } return htmlContent; };