用了 Hexo 的主题一个月了, 本文记录一下我为 Hexo Next 主题提交的第一个 PR: Safari 中无法 lazyload Disqus 的评论框.
背景
Next 主题在 Disqus 评论框的配置中的有一个选项: 开启 lazyload. 实现 Disqus 评论框延迟动态加载的效果.
1 | # Disqus |
但在 iPhone 上打开时, 就算拖动窗口到最底部, 评论框都不会开始加载. 怀疑是浏览器的问题, 果然在电脑上的 Safari 重现了.
分析代码
Disqus lazyload 逻辑的代码如下:
1 | {% if theme.disqus.lazyload %} |
首先声明几个概念:
- 网页顶部: 整个网站页面的最高点.
- 游览器窗口顶部: 当前游览器可视窗口的最高点.
代码逻辑
var offsetTop = $('#comments').offset().top - $(window).height();
获取的是: 评论框与网页顶部的距离 - 当前游览器窗口高度. 如果这个距离小于 0(offsetTop <= 0
), 说明没有滚动条(评论框与网页顶部的距离小于游览器窗口的高度), 所以可以直接加载评论框.
如果offsetTop > 0
, 就要在用户滚动页面窗口时, 实时的去取当前游览器窗口顶部与网页顶部的距离 scrollTop = document.documentElement.scrollTop
. 当这个值超过offsetTop
(可以理解为: $(offsetTop + windowHight >= '#comments').offset().top
), 就去加载评论框.
说的有点绕了, 总结就是当 Disqus 评论框开始进入游览器窗口时, 才会去加载. 但在 Safari 中, 实时的去取当前游览器窗口顶部与网页顶部的距离 scrollTop = document.documentElement.scrollTop
时, 返回的永远是 0. 导致了永远不会加载评论框的 bug.
解决问题
主要做了两个改动:
- 将
scrollTop = document.documentElement.scrollTop
替换为 Safari 兼容的scrollTop = $(window).scrollTop();
. - 实时的去获取
$('#comments').offset().top - $(window).height()
, 因为在调试的过程中, 发现这个值总是不准确, 原来是很多未加载的图片(lazyload) 没有高度造成的. 而且用户可能动态的去改变游览器的窗口大小, 所以感觉这个改动还是挺合理的.
具体代码:
1 | {% if theme.disqus.lazyload %} |
-eof-