前言
我利用空业余时间研究了JavaScript的交集观察者API,发现它有很棒的应用场景,比如图片或者内容的懒加载。笔者在之前的文章中也详细介绍了三种观察者的用法,包括位置监控、dom变化监控和窗口变化监控、。
这里有一个很常见的例子。平时喜欢看短视频的朋友可能会注意到,当我们浏览一个视频标题时,我们会滚动视频列表。当某个视频滚动到定位器的某个位置(一般可以认为是屏幕中央)时,该视频就会自动播放。移出指定区域后,视频将自动关闭,并播放下一个移入指定区域的视频,如下所示:
作为一个好奇心很强的前端工程师,有必要研究一下它的内部实现。
作者的第一个想法是通过监测滚动位置来判断某个视频元素是否到达指定区域。然而,这种方法需要处理很多情况,如边界条件判断和滚动方向判断等。而且频繁触发会导致性能问题。
好吧,我之前深入研究了一下
交集观察者API
,发现可以使用它提供的API,可以很方便的监控指定根元素下元素的位置变化,做一些自定义操作:
接下来我就直接用
交集观察者
提供的api来实现
视频在滚动时自动播放
的功能,如果不熟悉这个api,可以拿几个很有意思的javascript知识点总结一下
。笔者将使用流行的
Dplayer
,可以方便地操作视频显示,实现良好的独占播放控制,支持弹幕。
正文
根据上面的介绍,大致知道了具体要求。接下来,我们将基于
交集观察者API
来实现它。这个想法大致如下图所示:
具体的思路是,我们可以将
交集观察者
的根元素
的
rootMargin
(即根元素的外边缘)设置为上图中蓝色显示的区域,然后当视频完全进入该区域时(即
阈值
阈值为1时)由于我们使用的是
DP player
,我们只需要设置
互斥
属性关于设置
rootMargin
的知识,请参考下图:
rootMargin接收格式如下:”10px 0px 10px 0px & # 8221,数字从左到右分别代表上(上)右(右)下(下)左(左)边距,。-180 px 0px-180 px 0px ”这样,上下边距就会减少。当然,也可以根据需要设置不同的值。
有了上面的思路,我们就可以达到上面动画所示的效果。作者将使用react来实现它。在实施之前,我们会准备几个视频资料,然后实施清单的基本框架:
import React, { useEffect, useState } from 'react'import VideoItem from 'components/VideoItem'import styles from './videoList.less'const data = [ // 视频列表]function VideoList(props) { useEffect(() => { let observerVideo = new IntersectionObserver( (entries, observer) => { entries.forEach(entry => { // 当移入指定区域内后,播放视频 if(entry.intersectionRatio === 1) { // 一些操作 return } // 停止** // observer.unobserve(entry.target); }); }, { root: document.getElementById('scrollView'), rootMargin: '-180px 0px -180px 0px', threshold: 1 } ); document.querySelectorAll('.video-item').forEach(video => { observerVideo.observe(video) }); }, []) return <div className={styles.videoWrap}> <div className={styles.list} id="scrollView"> { data.***p(item => { return <VideoItem src={item} groupName="video-item" key={item} /> }) } </div> </div>}export default VideoList
我们将在后面介绍上面代码中的VideoItem组件。现在有一个问题,我们已经监测到了需要自动播放的视频元素,但是如何通知VideoItem组件让其播放呢?这里作者的想法是给VideoItem添加一个自定义属性,其值是当前视频的src。当我们监控一个需要播放的视频元素时,可以获取之前设置的自定义属性,然后作为prop传递给videoitem。当VideoItem组件**到prop的变化并且等于其自身的src时,它触发视频播放。代码如下:import React, { useEffect, useState } from 'react'import VideoItem from 'components/VideoItem'import styles from './videoList.less'const data = [ // 视频列表]function VideoList(props) { useEffect(() => { let observerVideo = new IntersectionObserver( (entries, observer) => { entries.forEach(entry => { // 当移入指定区域内后,播放视频 if(entry.intersectionRatio === 1) { // 一些操作 return } // 停止** // observer.unobserve(entry.target); }); }, { root: document.getElementById('scrollView'), rootMargin: '-180px 0px -180px 0px', threshold: 1 } ); document.querySelectorAll('.video-item').forEach(video => { observerVideo.observe(video) }); }, []) return <div className={styles.videoWrap}> <div className={styles.list} id="scrollView"> { data.***p(item => { return <VideoItem src={item} groupName="video-item" key={item} /> }) } </div> </div>}export default VideoList
以上步骤完成了基于指定区域自动播放视频的功能,效果如下:
最后
如果您想了解更多
H5游戏
、
webpack
、
node
Gulp
、
画布数据可视化[/S2/]等前端知识和实战,欢迎在趣谈前端专栏学习讨论,共同探索前端边界。
本文来自长街旧人投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/481384.html