轮播视频的概念极其适用场景和实现方法 你真的需要轮播视频吗
不懂了吧 网上的轮播视频粗略看一圈下来,基本都是把轮播图的img图片位置换成了video视频,这种时间一到就直接下一张的轮播并不符合我们的需求 我们需要的是可以获取到视频播放长度,在视频彻底播放完之后才轮播到下一个视频的真轮播视频。这个时候就需要用到我们深厚且扎实的js功底,以我自己的轮播视频为例,先简单写一下基础的HTML和css布局
以下是HTML的部分 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 <!doctype html > <html lang ="en" > <head > <meta charset ="UTF-8" > <meta name ="viewport" content ="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" > <meta http-equiv ="X-UA-Compatible" content ="ie=edge" > <title > 轮播视频</title > <link rel ="stylesheet" href ="banner.css" > </head > <body > <section id ="banner" > <div class ="videos-loop" > <div class ="vp-area" > <video muted autoplay > <source src ="supreme.mp4" type ="video/mp4" > </video > </div > <div class ="thumbnails" > <div class ="video-item playing" > <video muted > <source src ="supreme.mp4" type ="video/mp4" > </video > <div class ="video-item-content" > <h3 > There are birds that only land once in a lifetime.</h3 > <p > Do you want to know why? The time it landed was when it died.</p > </div > </div > <div class ="video-item" > <video muted > <source src ="nike.mp4" type ="video/mp4" > </video > <div class ="video-item-content" > <h3 > There are birds that only land once in a lifetime.</h3 > <p > Do you want to know why? The time it landed was when it died.Do you want to know why? The time it landed was when it died.Do you want to know why? The time it landed was when it died.Do you want to know why? The time it landed was when it died.Do you want to know why? The time it landed was when it died.</p > </div > </div > <div class ="video-item" > <video muted > <source src ="adidas.mp4" type ="video/mp4" > </video > <div class ="video-item-content" > <h3 > There are birds that only land once in a lifetime.</h3 > <p > Do you want to know why? The time it landed was when it died.</p > </div > </div > </div > </div > </section > </body > <script src ="banner.js" > </script > </html >
以下是CSS的部分 可以按需删减 ,此处的css随便写了几坨
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 #banner { margin-top : 100px ; width : 100% ; background-color : #000 ; box-sizing : border-box; }#banner .videos-loop { width : 1460px ; display : flex; justify-content : space-between; margin : 0 auto; }#banner .videos-loop .vp-area { width : 1100px ; height : calc (1100px * 9 / 16 ); background-color : #161616 ; }#banner .videos-loop .vp-area video { width : 1100px ; height : calc (1100px * 9 / 16 ); }#banner .videos-loop .thumbnails { width : calc (100% - 1100px ); height : calc (1100px * 9 / 16 ); overflow : hidden; display : flex; flex-direction : column; align-items : center; background-color : #1e1e1e ; }#banner .videos-loop .thumbnails .video-item { width : 320px ; height : calc (120px ); padding : 10px ; display : flex; transition : 0.5s ease-in-out; border-radius : 4px ; cursor : pointer; }#banner .videos-loop .thumbnails .video-item video { width : calc (320px * 0.4 ); height : calc (calc (320px * 0.4 ) * 9 / 16 ); object-fit : cover; margin-right : 15px ; margin-top : 20px ; }#banner .videos-loop .thumbnails .video-item .video-item-content { flex : 1 ; width : calc (calc (320px - calc (320px * 0.4 )) - 15px ); }#banner .videos-loop .thumbnails .video-item .video-item-content h3 { width : inherit; white-space : nowrap; overflow : hidden; text-overflow : ellipsis; font-size : 16px ; color : rgba (255 , 255 , 255 , 0.6 ); margin-bottom : 12px ; transition : 0.2s ease-in-out; }#banner .videos-loop .thumbnails .video-item .video-item-content p { width : inherit; overflow : hidden; text-overflow : ellipsis; display : -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2 ; font-size : 16px ; color : #ccc ; transition : 0.2s ease-in-out; }#banner .videos-loop .thumbnails .video-item :hover { background-color : #363636 ; }#banner .videos-loop .thumbnails .video-item :hover .video-item-content h3 { color : #ffffff ; }#banner .videos-loop .thumbnails .video-item :hover .video-item-content p { color : #ccc ; }#banner .videos-loop .thumbnails .video-item .playing { background-color : #363636 ; }#banner .videos-loop .thumbnails .video-item .playing .video-item-content h3 { color : #ffffff ; }#banner .videos-loop .thumbnails .video-item .playing .video-item-content p { color : #ccc ; }@media (min-width : 992px ) and (max-width : 1200px ) { #banner .videos-loop { width : 1160px ; display : flex; justify-content : space-between; margin : 0 auto; } #banner .videos-loop .vp-area { width : 800px ; height : calc (800px * 9 / 16 ); background-color : #161616 ; } #banner .videos-loop .vp-area video { width : 800px ; height : calc (800px * 9 / 16 ); } #banner .videos-loop .thumbnails { width : calc (100% - 800px ); height : calc (800px * 9 / 16 ); overflow : hidden; display : flex; flex-direction : column; align-items : center; background-color : #1e1e1e ; } }@media (min-width : 700px ) and (max-width : 992px ) { #banner .videos-loop { width : 860px ; display : flex; justify-content : space-between; margin : 0 auto; } #banner .videos-loop .thumbnails { width : calc (100% - 500px ); height : calc (650px * 9 / 16 ); overflow : hidden; display : flex; flex-direction : column; align-items : center; background-color : #1e1e1e ; } #banner .videos-loop .vp-area { width : 500px ; height : calc (500px * 9 / 16 ); background-color : #161616 ; } #banner .videos-loop .vp-area video { width : 500px ; height : calc (500px * 9 / 16 ); margin-top : 50px ; } }@media (max-width : 700px ) { #banner .videos-loop { width : 480px ; display : flex; flex-direction : column; justify-content : space-between; margin : 0 auto; } #banner .videos-loop .vp-area { width : 480px ; height : calc (500px * 9 / 16 ); background-color : #161616 ; } #banner .videos-loop .vp-area video { width : 480px ; height : calc (600px * 9 / 16 ); } #banner .videos-loop .thumbnails { width : calc (100% - 500px ); height : calc (500px * 9 / 16 ); overflow : hidden; display : flex; flex-direction : column; align-items : center; background-color : #1e1e1e ; } #banner .videos-loop .thumbnails .video-item { width : 500px ; height : calc (120px ); padding : 10px ; display : flex; transition : 0.5s ease-in-out; border-radius : 4px ; cursor : pointer; margin-bottom : 0 ; } #banner .videos-loop .thumbnails { width : 480px ; height : calc (670px * 9 / 16 ); overflow : hidden; display : flex; flex-direction : column; align-items : center; background-color : #1e1e1e ; } }
然后,把功能拆分,先实现轮播功能,这里就不细说了,直接上内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 let currIndex = 0 ; let playA = document .querySelector (".vp-area" ); let thumb = [...document .querySelectorAll (".thumbnails > .video-item > video" )]; let playTime = null ; let smWindow = undefined ; const bannerVideo = function (event ) { playA.children [0 ].removeEventListener ("ended" ,bannerVideo); document .querySelector (".playing" ).classList .remove ("playing" ); if (event.type != "click" ) currIndex = ++currIndex % thumb.length ; let videoDom = `<video muted autoplay> <source src="${thumb[currIndex].children[0 ].getAttribute("src" )} " type="video/mp4"> </video>` ; playA.innerHTML =videoDom; thumb[currIndex].parentElement .classList .add ("playing" ); playA.children [0 ].addEventListener ("ended" ,bannerVideo); }
然后就是缩略图功能,当鼠标移到缩略图范围内时,主视频区的视频暂停,开始播放缩略图视频,鼠标移开缩略图时,主视频继续播放,如果点击了指定的视频,则播放指定的视频
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 const smallVideo = function ( ) { let videos = document .querySelectorAll (".video-item" ); videos.forEach ((el,index ) => { el.addEventListener ("click" , (event ) => { if (smWindow != undefined ) { thumb[smWindow].pause (); thumb[smWindow].currentTime = 0 ; playA.children [0 ].play (); } if (currIndex == index) return ; currIndex = index; bannerVideo (event); }); el.addEventListener ("mouseover" ,() => { playTime = setTimeout (() => { smWindow = index; playA.children [0 ].pause (); thumb[index].play (); },100 ); }); el.addEventListener ("mouseleave" , () => { clearTimeout (playTime); setTimeout (()=> { smWindow = undefined ; thumb[index].pause (); thumb[index].currentTime = 0 ; playA.children [0 ].play (); },100 ); }); }); }
完整的js内容如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 (function ( ) { let currIndex = 0 ; let smWindow = undefined ; let playtime = null ; let thumb = [...document .querySelectorAll (".thumbnails > .video-item > video" )]; let playbanner = document .querySelector (".vp-area" ) const bannerVideo = function (event ) { if (event.type != "click" ) currIndex = ++currIndex % thumb.length ; let videoDom = `<video muted autoplay> <!-- 用插值表达式动态渲染src路径 thumb这个数组里面第currIndex个参数的第一个子元素source的视频路径--> <!-- getAttribute方法返回一个元素属性的值,这里返回的src相当于获取缩略图的的视频路径,根据缩略图的排序来划分视频播放列表--> <source src="${thumb[currIndex].children[0 ].getAttribute("src" )} " type="video/mp4"> </video>` playbanner.innerHTML = videoDom; playbanner.children [0 ].addEventListener ("ended" ,bannerVideo); } const smBannerVideo = function ( ) { let videos = document .querySelectorAll (".video-item" ); videos.forEach ((el,index ) => { el.addEventListener ("click" ,(event )=> { if (smWindow != undefined ) { thumb[smWindow].pause (); thumb[smWindow].currentTime = 0 ; playbanner.children [0 ].play (); } if (currIndex == index) return ; currIndex = index; bannerVideo (event); }) el.addEventListener ("mouseover" ,()=> { setTimeout (() => { smWindow = index; playbanner.children [0 ].pause (); thumb[index].play (); },100 ); }) el.addEventListener ("mouseleave" ,()=> { setTimeout (()=> { thumb[index].pause (); thumb[index].currentTime = 0 ; playbanner.children [0 ].play (); },100 ); }) }); } const run = function ( ) { let videoElem = playbanner.children [0 ]; videoElem.addEventListener ("ended" , bannerVideo); smBannerVideo (); } run (); })()
小结 那么到此为止,一套完整的轮播视频+缩略图就这么点了 虽然细节没有说到位,但是反复看两遍源码,逻辑还是很简单的,点到为止,下播