From 21e7b7667c0bc4759e46f6bc06413bdb72185c9d Mon Sep 17 00:00:00 2001 From: tolking Date: Tue, 7 Jul 2020 21:59:23 +0800 Subject: [PATCH] feat: add IntersectionObserver --- ImgLazy.vue | 2 +- checkSrc.js | 19 ---------------- docs/.vuepress/config.js | 5 +---- enhanceAppFile.js | 48 +++++++++++++++++++++++++++++----------- index.js | 31 +++++++++++++++----------- 5 files changed, 55 insertions(+), 50 deletions(-) delete mode 100644 checkSrc.js diff --git a/ImgLazy.vue b/ImgLazy.vue index 9059ca3..ef4a269 100644 --- a/ImgLazy.vue +++ b/ImgLazy.vue @@ -2,7 +2,7 @@ diff --git a/checkSrc.js b/checkSrc.js deleted file mode 100644 index eb56d98..0000000 --- a/checkSrc.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; - -module.exports = function check_src(md, options) { - var base = options.base - var defaultImageRenderer = md.renderer.rules.image || function (tokens, idx, options, env, self) { - return self.renderToken(tokens, idx, options); - }; - - md.renderer.rules.image = function (tokens, idx, options, env, self) { - var token = tokens[idx]; - var srcValue = token.attrGet('src'); - - if (srcValue && srcValue.charAt(0) === '/' && !srcValue.startsWith(base)) { - token.attrSet('src', base + srcValue.slice(1)); - } - - return defaultImageRenderer(tokens, idx, options, env, self); - }; -}; diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 9e1b56a..ec0fa87 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -57,9 +57,6 @@ module.exports = { } }, plugins: [ - [require.resolve('../../index.js'), { - useLoading: true, - selector: 'lazy' - }] + [require.resolve('../../index.js')] ] } diff --git a/enhanceAppFile.js b/enhanceAppFile.js index b7c1ae5..ee0267d 100644 --- a/enhanceAppFile.js +++ b/enhanceAppFile.js @@ -4,26 +4,48 @@ export default ({ Vue }) => { Vue.mixin({ data() { return { - $imgLazyObserver: {} - } - }, - - computed: { - $supLoading() { - return config.useLoading && "loading" in HTMLImageElement.prototype + $io: undefined } }, mounted() { - if (this.$supLoading) { - const lazyEls = document.querySelectorAll('img.' + config.selector) + const lazyEls = document.querySelectorAll('img.' + config.selector) + if (config.useNative && 'loading' in HTMLImageElement.prototype) { lazyEls.forEach(lazyEl => { - !lazyEl.getAttribute("src") && lazyEl.setAttribute("src", lazyEl.getAttribute("data-src")) + !lazyEl.getAttribute('src') && lazyEl.setAttribute('src', lazyEl.getAttribute('data-src')) }) } else { - const lozad = require('lozad') - this.$imgLazyObserver = lozad('img.' + config.selector) - this.$imgLazyObserver.observe() + this.setObserver() + lazyEls.forEach(lazyEl => { + this.$io.observe(lazyEl) + }) + } + }, + + methods: { + setObserver() { + this.$io = new IntersectionObserver(entries => { + entries.forEach(item => { + if (item.isIntersecting) { + const src = this.getSrc(item.target) + + if (src) { + item.target.src = src + } + this.$io.unobserve(item.target) + } + }) + }, { + rootMargin: config.rootMargin + }) + }, + getSrc(el) { + if (el.dataset) { + return el.dataset.src + } else { + const item = el.attributes.find(item => item.nodeName === 'data-src') + return item && item.nodeValue + } } } }) diff --git a/index.js b/index.js index a708327..b1aebf6 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,18 @@ -const { path } = require('@vuepress/shared-utils') +const path = require('path') module.exports = (options, ctx) => { - const { - useLoading = true, - selector = 'lazy' - } = options + const selector = options && options.selector ? options.selector : 'lazy' + const rootMargin = options && options.rootMargin ? options.rootMargin : '200px' + const useNative = options && typeof options.useNative === 'boolean' + ? options.useNative + : options && typeof options.useLoading === 'boolean' + ? options.useLoading + : true + const prefix = options && options.prefix + ? options.prefix + : src => src && src.charAt(0) === '/' && !src.startsWith(ctx.base) + ? ctx.base + src.slice(1) + : src return { name: 'vuepress-plugin-img-lazy', @@ -25,18 +33,15 @@ module.exports = (options, ctx) => { }, extendMarkdown: md => { - md.use(require('markdown-it-img-lazy'), { useLoading, selector }) - md.use(require('./checkSrc.js'), { base: ctx.base }) + md.use(require('markdown-it-img-lazy'), { useNative, selector, prefix }) md.use(require('markdown-it-imsize')) }, async clientDynamicModules () { - return [ - { - name: 'imgLazy.js', - content: `export default ${JSON.stringify({ useLoading, selector })}` - } - ] + return [{ + name: 'imgLazy.js', + content: `export default ${JSON.stringify({ useNative, selector, rootMargin })}` + }] }, enhanceAppFiles: path.resolve(__dirname, 'enhanceAppFile.js')