日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Javascript如何實(shí)現(xiàn)類似西瓜視頻的視頻隊(duì)列自動(dòng)播放?

前言

去年利用空余時(shí)間研究了一下javascript的Intersection Observer API,發(fā)現(xiàn)其有很大的應(yīng)用場景,比如圖片或者內(nèi)容的懶加載,視差動(dòng)畫等。我也在之前的文章中詳細(xì)介紹了3種Observer(觀察者)的用法,包括位置監(jiān)聽,dom變化監(jiān)聽以及窗口變化監(jiān)聽,它們有非常多的應(yīng)用場景,所以很有必要研究明白, 感興趣的可以讀完本片文章之后學(xué)習(xí)一下(幾個(gè)非常有意思的javascript知識(shí)點(diǎn)總結(jié)).

專注于為中小企業(yè)提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)扎魯特旗免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了近千家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

這里有一個(gè)很常見的例子,平時(shí)喜歡看短視頻的朋友可能會(huì)注意到,我們在瀏覽某視頻頭條時(shí),滾動(dòng)視頻列表,當(dāng)某一個(gè)視頻滾動(dòng)到手機(jī)的一定位置時(shí)(一般可以看成是屏幕中心),該視頻會(huì)自動(dòng)播放,當(dāng)移出指定區(qū)域后視頻會(huì)自動(dòng)關(guān)閉并播放移入指定區(qū)域的下一個(gè)視頻,如下:

作為一名好奇心極強(qiáng)的前端工程師,有必要好好研究一下其內(nèi)部實(shí)現(xiàn)。

我的第一思路就是監(jiān)聽滾動(dòng)位置來判斷某個(gè)視頻元素是否到達(dá)指定區(qū)域內(nèi),但是這種方式需要處理的條件很多,比如邊界條件判斷,滾動(dòng)方向判斷等,而且頻繁觸發(fā)還會(huì)出現(xiàn)性能問題。

好在之前深入研究過Intersection Observer API,發(fā)現(xiàn)可以使用它提供的API,很方便的監(jiān)聽到元素在指定根元素下的位置變化,并做一些自定義操作:

接下來我將利用Intersection Observer提供的api來實(shí)現(xiàn)視頻在滾動(dòng)的過程中自動(dòng)播放的功能,如果對該api不太熟悉的朋友可以移步

幾個(gè)非常有意思的javascript知識(shí)點(diǎn)總結(jié)

視頻播放插件筆者將使用比較流行的Dplayer,它可以很方便的操作視頻的展現(xiàn)并實(shí)現(xiàn)很好的排他性播放控制,并且支持彈幕。

正文

根據(jù)以上的介紹我們大致了解了具體的需求,接下來我們就來基于Intersection Observer API實(shí)現(xiàn)一下它。思路大致如下圖所示:

具體思路就是我們可以把Intersection Observer的根元素的rootMargin(即根元素的外邊距)設(shè)置為如上圖藍(lán)色所示區(qū)域,然后當(dāng)視頻完全進(jìn)入該區(qū)域內(nèi)后(也就是thresholds閾值為1時(shí)),觸發(fā)當(dāng)前視頻的播放即可。因?yàn)槲覀兪褂玫氖荄player,所以我們只要將其配置屬性中的mutex屬性設(shè)置為true(為true時(shí)會(huì)阻止多個(gè)播放器同時(shí)播放,當(dāng)前播放器播放時(shí)暫停其他播放器)。有關(guān)設(shè)置rootMargin的知識(shí),可以參考下圖介紹:

rootMargin接收格式如下:"10px 0px 10px 0px",從左到右數(shù)字依次代表top(上) right(右) bottom(下) left(左)邊距,當(dāng)然我們單位也可以使用百分比(%),為正值時(shí)代表擴(kuò)大更元素的邊距范圍,負(fù)值代表縮小根元素的邊距范圍,這里我們應(yīng)該縮小范圍,所以rootMargin我們可以這么設(shè)置"-180px 0px -180px 0px",這樣上下的邊距就會(huì)縮小,當(dāng)然大家也可以根據(jù)需求設(shè)置不同的值。

有了以上思路之后我們就可以實(shí)現(xiàn)上文動(dòng)圖所展示的效果了。筆者將采用react來實(shí)現(xiàn),在實(shí)現(xiàn)之前我們先準(zhǔn)備幾個(gè)視頻素材,然后實(shí)現(xiàn)列表基本框架:

 
 
 
 
  1. import React, { useEffect, useState } from 'react' 
  2. import VideoItem from 'components/VideoItem' 
  3. import styles from './videoList.less' 
  4.  
  5. const data = [ 
  6.     // 視頻列表 
  7.  
  8. function VideoList(props) { 
  9.   useEffect(() => { 
  10.     let observerVideo = new IntersectionObserver( 
  11.         (entries, observer) => { 
  12.             entries.forEach(entry => { 
  13.                 // 當(dāng)移入指定區(qū)域內(nèi)后,播放視頻 
  14.                 if(entry.intersectionRatio === 1) { 
  15.                     // 一些操作 
  16.                     return 
  17.                 } 
  18.                 // 停止監(jiān)聽 
  19.                 // observer.unobserve(entry.target); 
  20.               }); 
  21.             }, 
  22.             { 
  23.               root: document.getElementById('scrollView'), 
  24.               rootMargin: '-180px 0px -180px 0px', 
  25.               threshold: 1 
  26.             } 
  27.         ); 
  28.         document.querySelectorAll('.video-item').forEach(video => { observerVideo.observe(video) }); 
  29.   }, []) 
  30.   return  
  31.      
  32.         { 
  33.             data.map(item => { 
  34.                 return  
  35.             }) 
  36.         } 
  37.     
 
  •   
  •  
  •  
  • export default VideoList 
  • 以上代碼中VideoItem組件我們后面會(huì)介紹,現(xiàn)在有個(gè)問題是我們已經(jīng)監(jiān)聽到了需要自動(dòng)播放的視頻元素,但是我們?nèi)绾瓮ㄖ猇ideoItem組件讓其播放呢?這里筆者實(shí)現(xiàn)思路是給VideoItem添加一個(gè)自定義屬性,該屬性的值就是當(dāng)前video的src,我們在監(jiān)聽到某個(gè)視頻元素需要播放時(shí),我們可以獲取到之前設(shè)置的自定義屬性,然后作為prop傳給VideoItem,當(dāng)VideoItem組件監(jiān)聽到該prop變化時(shí),并且等于自身的src,此時(shí)則觸發(fā)視頻播放。代碼如下:

     
     
     
     
    1. // VideoItem.js 
    2. import React, { useRef, useEffect } from 'react'; 
    3. import DPlayer from 'dplayer'; 
    4.  
    5. export default (props) => { 
    6.     let videoRef = useRef(null) 
    7.     let dpRef = useRef(null) 
    8.     let { src, groupName, curPlaySrc } = props 
    9.     useEffect(() => { 
    10.         dpRef.current = new DPlayer({ 
    11.             container: videoRef.current, 
    12.             screenshot: true, 
    13.             video: { 
    14.                 url: src, 
    15.                 thumbnails: 'logo.png' 
    16.             }, 
    17.             logo: 'logo.png' 
    18.         }); 
    19.     }, []) 
    20.  
    21.     useEffect(() => { 
    22.         // 當(dāng)當(dāng)當(dāng)前應(yīng)該播放的視頻url等于當(dāng)前視頻組件的src時(shí),播放視頻 
    23.         if(curPlaySrc === src) { 
    24.             dpRef.current.play() 
    25.         } 
    26.     }, [curPlaySrc]) 
    27.     return  
    28.         
     
  •     
  •  
  • 此時(shí)視頻列表頁代碼如下:

     
     
     
     
    1. // ... 
    2. function VideoList(props) { 
    3.   const [curPlaySrc, setCurPlaySrc] = useState('') 
    4.   useEffect(() => { 
    5.     let observerVideo = new IntersectionObserver( 
    6.         (entries, observer) => { 
    7.             entries.forEach(entry => { 
    8.                 // 當(dāng)移入指定區(qū)域內(nèi)后,播放視頻 
    9.                 if(entry.intersectionRatio === 1) { 
    10.                     // 設(shè)置當(dāng)前因該播放的視頻url 
    11.                     setCurPlaySrc(entry.target.dataset.src) 
    12.                     return 
    13.                 } 
    14.               }); 
    15.             }, 
    16.             { 
    17.               root: document.getElementById('scrollView'), 
    18.               rootMargin: '-180px 0px -180px 0px', 
    19.               threshold: 1 
    20.             } 
    21.         ); 
    22.         document.querySelectorAll('.video-item').forEach(video => { observerVideo.observe(video) }); 
    23.   }, []) 
    24.   return  
    25.      
    26.         { 
    27.             data.map(item => { 
    28.                 return  
    29.             }) 
    30.         } 
    31.     
     
  •   
  •  
  • 以上步驟即完成了基于指定區(qū)域自動(dòng)播放視頻的功能,效果如下:

    體驗(yàn)地址

    視頻自動(dòng)播放demo

    仿微信朋友圈動(dòng)態(tài)demo

    最后

    如果想學(xué)習(xí)更多H5游戲, webpack,node,gulp,css3,javascript,nodeJS,canvas數(shù)據(jù)可視化等前端知識(shí)和實(shí)戰(zhàn),歡迎在公號《趣談前端》加入我們的技術(shù)群一起學(xué)習(xí)討論,共同探索前端的邊界。


    網(wǎng)站題目:Javascript如何實(shí)現(xiàn)類似西瓜視頻的視頻隊(duì)列自動(dòng)播放?
    鏈接URL:http://www.5511xx.com/article/cosgoop.html