阅读本文约需要5分钟
大家好,我是你们的导师,我每天都会给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈)。上次给大家分享了js keyframes动画,今天跟大家分享下滚动容器尺寸变化。
1. 先从需求说起
对于一个宽度不固定的滚动容器,如果里面内容已经滚动到了一定的高度,这个时候滚动容器的宽度发生变化,则里面内容的位置会进行重定位,一不留神就不知道刚才的位置是哪里了。
尤其是看小说这种非常考验眼力的场景。例如下面的GIF截图演示:
于是,就有需求。当滚动容器尺寸发生变化的时候(如宽屏窄屏切换,或者默认尺寸变全屏时候),最上面元素位置要保持不变,这样视觉体验就很好。不会因为突然的尺寸变化而不知道刚才看到哪里了。
那么该如何实现呢?需要借助JavaScript手动修正滚动位置。
2. 滚动容器尺寸变化子元素视觉上位置不变的JS处理
我们先看实现后的截屏gif效果:
滚动容器到合适位置,然后改变浏览器窗口尺寸,可以体验到微丝不动的非常友好的交互体验效果。
3. JS实现的原理
1)获得最靠近滚动容器上边缘的元素;
2)获得最靠近滚动容器上边缘的元素距离上边缘的距离;
3)当滚动容器尺寸改变后,获得之前最靠近上边缘元素现在距离上边缘的距离,根据前后的差值修正此时的scrollTop大小。
原理第一步是最难点,如何获得最靠近滚动容器上边缘的元素呢?我这里使用的是document.elementsFromPoint方法,语法如下:
表示返回所有距离浏览器可视窗口x, y坐标的DOM元素集合。因此,elements是一个从最子元素开始,依次向上,一直到,元素的类数组集合。
在本例中,elements[0]就是我们需要的元素。
假设滚动容器元素的id是box,则使用JavaScript代码表示就是:
然后target距离上边缘的距离也很好实现(容器scroll事件时候执行):
最后,根据滚动后的边缘距离进行滚动修正(窗体resize事件时候执行):
4. 关于document.elementsFromPoint API的兼容性
根据MDN上的数据,document.elementsFromPoint IE10+才支持,而且需要ms私有前缀,因此,如果想要兼容IE浏览器,可以加一句:
由于本文实例属于体验增强的功能,因此,就算浏览器不支持也无伤大雅,能够让90+%浏览器有更好体验已经很棒了,因此是可以放心大胆使用的一个技术案例。
5. IE浏览器下更多细节
在IE浏览器下测试,resize时候滚动内容有晃动,我猜测可能与边缘位置计算带小数有关,因此,offsetTop的计算都是取整的,如下示意:
体验果然好了很多。另外,在Chrome等浏览器下,target的获取和偏移计算可以直接在window resize时候执行。但是IE浏览器不行,似乎IE浏览器先触发浏览器行为,再执行了resize事件,所以,综合下来,还是建议最上边缘元素获取放在scroll事件中处理。
今天就分享到这,今日留言话题:今天这个功能很棒吧?一起来说说吧,对于有价值的留言,我们都会一一回复的。如果觉得对你有一丢丢帮助,请点右下角【在看】,让更多人看到该文章。
【我们直招】很苦逼,但工资超级高!