问题解决
2022-03-09
由于 文章时效性提示 会导致懒加载和其他插件异常(因为用了 innerHTML)。改为
1 2 3
| posts[0].insertAdjacentHTML('afterbegin', '<div class="note note-warning" style="font-size:0.9rem"><p>' + '<div class="h6">文章时效性提示</div><p>这是一篇发布于 ' + days + ' 天前的文章,部分信息可能已发生改变,请注意甄别。' + '</p></p></div>');
|
后正常
问题所在
不知道是哪方的 BUG,首次加载和 http/s 下加载都正常。
而在 ServiceWorker 下, IntersectionObserver.entries.isIntersecting 返回都是 false,导致评论框和 lazyload 图片不显示。
导致问题的原因是 PWA 加载太快,导致 DOM 还没渲染完成就执行了io.observe(document.getElementById(targetId));
并且由于没有获取到元素信息(entries[0].intersectionRect
为空),所以就不会有元素可视的回调。
解决方案就是增加失败后 Rollback 到 scroll
模式判断是否可见。详见下面的代码。
函数位置
/source/js/utils.js
waitElementVisible
1 2 3 4 5 6 7 8 9 10
| var io = new IntersectionObserver(function(entries, ob) { if (entries[0].isIntersecting) { callback && callback(); ob.disconnect(); } }, { threshold : [0], rootMargin: (window.innerHeight || document.documentElement.clientHeight) + 'px' }); io.observe(document.getElementById(targetId));
|
解决方法/思路
评论换成 js 判断加载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| if (!isBot && runningOnBrowser){
if('attachEvent' in window)document.attachEvent("scroll", _callback); if('addEventListener' in window)document.addEventListener('scroll', _callback); function _callback() { const _target = document.getElementById(targetId); let visibleBottom = window.scrollY + document.documentElement.clientHeight; let visibleTop = window.scrollY; let centerY = _target.offsetTop + (_target.offsetHeight / 2); if (centerY > visibleTop && centerY < visibleBottom) { if('attachEvent' in window)document.detachEvent('scroll', _callback); if('addEventListener' in window)document.removeEventListener('scroll', _callback); callback && callback(); } }
|
新的方法
更新 2021 年 03 月 17 日 19 点 10 分
直接重写整个waitElementVisible
函数,正常的情况下使用IntersectionObserver
,失败的情况下回退到使用scroll
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
| waitElementVisible: function(targetId, callback) { var runningOnBrowser = typeof window !== 'undefined'; var isBot = (runningOnBrowser && !('onscroll' in window)) || (typeof navigator !== 'undefined' && /(gle|ing|ro|msn)bot|crawl|spider|yand|duckgo/i.test(navigator.userAgent)); var supportsIntersectionObserver = 'IntersectionObserver' in window; var attachEvent = 'attachEvent' in window; var addEventListener = 'addEventListener' in window; if (!isBot && runningOnBrowser && (attachEvent || addEventListener)) { var _scroll = function() { var _callback = function() { var _target = document.getElementById(targetId); var visibleBottom = window.scrollY + document.documentElement.clientHeight; var visibleTop = window.scrollY; var centerY = _target.offsetTop + (_target.offsetHeight / 2); if (centerY > visibleTop && centerY < visibleBottom) { if (attachEvent)document.detachEvent('scroll', _callback); if (addEventListener)document.removeEventListener('scroll', _callback); callback && callback(); } }; if (attachEvent)document.attachEvent('scroll', _callback); if (addEventListener)document.addEventListener('scroll', _callback); }; if (supportsIntersectionObserver) { var io = new IntersectionObserver(function(entries, ob) { if (entries[0].intersectionRect.x <= 0) { _scroll(); ob.disconnect(); return; } if (entries[0].isIntersecting) { callback && callback(); ob.disconnect(); } }, { threshold : [0], rootMargin: (window.innerHeight || document.documentElement.clientHeight) + 'px' }); io.observe(document.getElementById(targetId)); } else { _scroll(); } } else { callback && callback(); } },
|
图片加载我直接换了一个库
使用了lazyloadjs.cn
的 js 加载
scripts/events/lib/lazyload.js
第 32-35 行改为
1 2 3 4 5
| if (/data-src=/i.test(str)) { return str; } return str.replace(p1, `${loadingImage}" class="lazyload" data-src="${p1}`);
|
如果开启了 progressbar,相应的/source/js/plugins.js
内
var images = $('main img:not([srcset])');
也要修改为
var images = $('main img:not([data-src])');
至此修改完成.
题外话。提交了 pr 到 fluid-dev,结果失败,出现了 50 多个错误,看了一下,竟然全都是语法错误,惭愧惭愧