前言笔者利用业余时间研究了javascript的IntersectionObserverAPI,发现其应用场景非常多,比如图片或内容的延迟加载,视差动画等。这里是一个很常见的例子。平时喜欢看短视频的朋友可能会注意到,当我们浏览某个视频的头条时,会滚动视频列表。屏幕中心),视频会自动播放,当它移出指定区域时,视频会自动关闭并播放移入指定区域的下一个视频,如下:作为一个很好奇的前端工程师,有必要研究一下它的内部实现。作者的第一个想法是通过监听滚动位置来判断某个视频元素是否到达指定区域,但是这种方法需要处理很多条件,比如边界条件判断,滚动方向判断等,频繁触发也会导致性能问题。好在笔者之前深入研究过IntersectionObserverAPI,发现其提供的API可以方便的监听指定根元素下元素的位置变化,并进行一些自定义操作:笔者将直接使用IntersectionObserver提供的api用于实现滚动过程中自动播放视频的功能。视频播放插件作者会使用时下流行的Dplayer,可以方便的操作视频的显示,实现不错的专属播放控制,支持弹幕。根据上面的介绍,我们对具体的需求有了一个大致的了解,接下来我们将基于IntersectionObserverAPI进行实现。思路大致如下图所示:具体思路是我们可以将IntersectionObserver的根元素的rootMargin(即根元素的外边距)设置为上图中蓝色所示的区域如图,然后当视频完全进入该区域时(即thresholds阈值为1时),触发当前视频的播放。因为我们使用的是Dplayer,所以只需要将其配置属性中的mutex属性设置为true即可(会防止多个玩家同时播放,当前播放时暂停其他播放)。设置rootMargin的知识可以参考下图:rootMargin的接收格式如下:“10px0px10px0px”,从左到右的数字分别代表top(上)right(右)bottom(下)left(左)边距,当然我们的单位也可以用百分比(%)。为正值时表示扩大更多元素的边距范围,为负值时表示缩小根元素的边距范围。这里要缩小范围,所以我们可以这样设置rootMargin:“-180px0px-180px0px”,这样上下边距就会缩小。当然你也可以根据自己的需要设置不同的值。有了以上思路,我们就可以实现上面动图所示的效果了。笔者将使用react来实现。在实现之前,我们会准备好几个视频素材,然后实现列表的基本框架:constdata=[//videolist]functionVideoList(props){useEffect(()=>{letobserverVideo=newIntersectionObserver((entries,observer)=>{entries.forEach(entry=>{//移入后指定区域,播放视频if(entry.intersectionRatio===1){//部分操作返回}//停止监听//observer.unobserve(entry.target);});},{root:document.getElementById('scrollView'),rootMargin:'-180px0px-180px0px',threshold:1});document.querySelectorAll('.video-item').forEach(video=>{observerVideo.observe(video)});},[])返回
