滑动代码
1 /** 2 * 滑动处理 3 */ 4 function Touch() { 5 this.init(); 6 } 7 Touch.fn = Touch.prototype; 8 Touch.fn.init = function (params) { 9 var self = this; 10 dataStore.lastY = dataStore.translateY;//记录当前位移 11 self.startY = 0; 12 self.moveY = 0; 13 // self.lock = 0;//如果在回调或上升阶段不允许滑动. 14 self.bodyHeight = window.innerHeight; 15 self.resetLimitY(); 16 self.isIOS = /ip(?:hone|ad|od)/.test(navigator.userAgent.toLowerCase()); 17 ['touchstart','touchmove','touchend'].forEach(function (str) { 18 document.addEventListener(str,self[str].bind(self)); 19 }); 20 } 21 Touch.fn.touchstart = function(e){ 22 var self = this; 23 if(dataStore.lock) return; 24 self.startY = e.touches[0].pageY; 25 self.start = Date.now();//标识滑动起始时间,也用于标识滑动start 26 } 27 Touch.fn.move = function (y) { 28 dataStore.translateY = y; 29 } 30 Touch.fn.touchmove = function(e){ 31 var self = this; 32 if(dataStore.lock||!self.start) return;//锁定了,或者没有start,主要是手势一直滑动情况,已经加速度划走了,手势需要松开再重新开始 33 self.moveY = e.touches[0].pageY - self.startY; 34 self.move(self.moveY+ dataStore.lastY); 35 self.detect(); 36 } 37 Touch.fn.detect = function(isEnd){ 38 var self = this; 39 // console.log(self.moveY+" "+(Date.now()-self.start)); 40 var a = Math.abs(self.moveY)/(Date.now()-self.start)>=0.5; 41 if(isEnd){ 42 if(a){ 43 self.limitY = 0; 44 } 45 self.movend(); 46 return; 47 } 48 if(self.isIOS&&a){//IOS,可以在touchmove时直接滑动,体验流畅。 49 self.limitY = 0; 50 self.movend(); 51 } 52 53 } 54 Touch.fn.resetLimitY = function () { 55 this.limitY = this.bodyHeight/3;//位移多少才下滑 56 } 57 Touch.fn.touchend = function (e) { 58 var self = this; 59 if(dataStore.lock||self.moveY==0||!self.start) return; 60 self.detect(1); 61 } 62 Touch.fn.movend = function () { 63 // if(dataStore.lock) return; 64 // dataStore.lock = 1; 65 var self = this; 66 /*** 67 * 最后上下位移小于最小值则还原为上一次位移, 68 * 否则,那么就需要上移或下移一个body宽度,上移则translate加,下移在减去一个body 69 * 这里是计算出了应该位移高度。 70 */ 71 var transformY = Math.abs(self.moveY)<self.limitY?dataStore.lastY:dataStore.lastY+self.bodyHeight*(self.moveY>0?1:-1); 72 73 /*** 74 * 还需计算最大下滑高度和最大上滑高度 75 */ 76 var listUL = document.querySelector(".quan_vcd_list"); 77 var listHeight = listUL.getBoundingClientRect().height; 78 79 //如果是最后一个li,则不能下滑, 80 var maxBottom = (listHeight - self.bodyHeight)*-1; 81 var lastComputeY = transformY>0?0:transformY<maxBottom?maxBottom:transformY; 82 //停止滑动之后,自动滚动距离,transition 83 listUL.classList.add('trans'); 84 85 if(lastComputeY<=0){ 86 var d = lastComputeY-dataStore.lastY; 87 d&&events.trigger("touch_move",d,(-lastComputeY/self.bodyHeight)); 88 } 89 self.start = 0; 90 var raf = window.requestAnimationFrame|| window.webkitRequestAnimationFrame; 91 raf(function () { 92 self.move(lastComputeY); 93 self.moveY = 0; 94 dataStore.lastY = lastComputeY;//记录确定的位置 95 if(listHeight+dataStore.lastY<=self.bodyHeight){ 96 events.trigger("turnPage"); 97 } 98 setTimeout(function () { 99 listUL.classList.remove("trans"); 100 dataStore.lock = 0; 101 self.resetLimitY(); 102 },500); 103 }); 104 }
1 exports.init = function (opt) { 2 var config = { 3 props:['feedData','index'], 4 data:function () { 5 return { 6 play_btn:0, 7 bg_name:"", 8 anim_like:[], 9 vloading:0 10 } 11 }, 12 mounted:function(){ 13 addEvent(this); 14 this.stall = 0; 15 this.loaderror = 0; 16 }, 17 methods:{ 18 playBtn:function(){ 19 this.play(); 20 }, 21 onerror:function(){ 22 errors(this,"error:"); 23 }, 24 onbort:function(){ 25 errors(this,"bort:"); 26 }, 27 onstalled:function () { 28 var self = this; 29 if(!self.feedData.start) return; 30 self.vloading = 1; 31 self.play(); 32 self.stall++; 33 if(self.stall==2){ 34 util.showTip("网络有点慢哦~"); 35 store.report(27,1); 36 } 37 }, 38 onplaying:function(){ 39 var self = this; 40 compute(self); 41 self.play_btn = 0; 42 self.wa("138146.34.1"); 43 store.report(27,0); 44 }, 45 onpause:function(){ 46 setPlay(this,1); 47 }, 48 waiting:function () { 49 var self = this; 50 clearInterval(self.timer); 51 self.loadTimes = 0; 52 self.timer = setInterval(function () { 53 self.loadTimes++; 54 if (self.loadTimes >= 2) {//连续3次未播放,当作是卡住了 55 self.aPause(); 56 self.vloading = 1; 57 } 58 }, 1800); 59 }, 60 ondurationchange:function(){ 61 compute(this); 62 }, 63 onloadedmetadata:function(){ 64 compute(this); 65 }, 66 ontimeupdate:function(){ 67 timeupdate(this); 68 }, 69 aPause:function(){ 70 var self = this; 71 self.audio&&self.audio.pause(); 72 }, 73 aPlay:function(){ 74 var self = this; 75 self.audio&&self.audio.play(); 76 }, 77 pause:function(){ 78 var self= this; 79 self.video.pause(); 80 self.aPause(); 81 self.vloading = 0; 82 clearInterval(self.timer); 83 }, 84 play:function(isMove){ 85 videoPlay(this,isMove); 86 }, 87 checkLoading:function(){ 88 checkLoading(this); 89 }, 90 show_ani:function (e) { 91 showAni(this,e); 92 }, 93 click_pause:function (e) { 94 clickPause(this,e); 95 }, 96 onx5videoexitfullscreen:function (params) { 97 this.video.play(); 98 }, 99 hideAll:function () { 100 console.log("hideAll"); 101 } 102 103 } 104 }; 105 Vue.component('video-com',util.assign(config,opt)); 106 } 107 /** 108 * 视频暂停 109 * @param {*} self 110 */ 111 function clickPause(self,e) { 112 var feed = self.feedData; 113 if(feed.goods_show){ 114 feed.goods_show = 0; 115 feed.hideOpt = 0; 116 return; 117 } 118 if(feed.input_show==0&&feed.comments_show){ 119 feed.hideOpt = 0; 120 feed.comments_show = 0; 121 return; 122 } 123 if(feed.input_show){//评论的时候,不允许操作。 124 return; 125 } 126 if(self.dt>0){ 127 self.show_ani(e); 128 return; 129 } 130 self.dt = setTimeout(function () { 131 self.dt = 0; 132 },400); 133 134 if(self.t||Date.now-self.dbclick<1500){//dbclick之后,1.5秒不响应点击播放暂停 135 return; 136 } 137 self.t = setTimeout(function () { 138 self.t = 0; 139 if(self.play_btn){ 140 self.play(); 141 }else{ 142 self.pause(); 143 } 144 },600); 145 } 146 /** 147 * 双击视频动画 148 * @param {*} self 149 */ 150 function showAni(self,e) { 151 clearTimeout(self.t); 152 self.t = 0; 153 clearTimeout(self.dt); 154 self.dt = 0; 155 self.dbclick = Date.now(); 156 var feed = self.feedData; 157 if(!(feed.commentid>0)&&!self.praising){ 158 self.praising = 1; 159 store.add_praise(feed,function () { 160 self.praising = 0; 161 },detailUtil.getOnePic(feed)); 162 } 163 var like = self.anim_like; 164 var len = like.length; 165 if(len>=8){ 166 like.splice(0,len-5); 167 } 168 like.push({x:e.pageX-100,y:height*this.index+e.pageY - 100}); 169 } 170 /** 171 * 检测下载是否完成 172 * @param {*} self 173 */ 174 function checkLoading(self) { 175 var interval = window.setInterval(getLoaded,100); 176 // 获取视频已经下载的时长 177 function getLoaded() { 178 var end = 0; 179 try { 180 end = parseInt(self.video.buffered.end(0) || 0)+2; 181 } catch(e) { 182 } 183 if(end>=self.duration){ 184 clearInterval(interval); 185 self.loadedAll = 1; 186 var nextItem = store.store.feedList[self.index+1]; 187 if(nextItem){//存在下一条 188 //没有播放视频,既还没有加载完成。 189 if(!nextItem.playurl) nextItem.playurl = nextItem.videourl; 190 //有背景音乐,但是播放的背景音乐未加载完成,则开始加载 191 if(!nextItem.bgmurl_p&&nextItem.bgmurl){ 192 nextItem.bgmurl_p = nextItem.bgmurl; 193 } 194 } 195 196 } 197 return end 198 } 199 } 200 /** 201 * 播放视频 202 * @param {*} self 203 */ 204 function videoPlay(self,isMove) { 205 self.play_btn = 0; 206 207 self.aPlay(); 208 209 isMove&&(self.video.currentTime = 0); 210 if(self.audio){ 211 self.video.volume = 0; 212 self.video.muted =1; 213 } 214 var feed = self.feedData; 215 if(!feed.playurl){ 216 feed.playurl = feed.videourl; 217 self.video.load(); 218 } 219 self.video.play(); 220 isMove&&setTimeout(function (paras) { 221 222 if(isIOS&&!feed.start&&window.isXCX==1){ 223 self.play_btn = 1; 224 clearInterval(self.timer); 225 }else if(!feed.start){ 226 setTimeout(function () { 227 if(feed.start) return; 228 setPlay(self,1); 229 clearInterval(self.timer); 230 },2000); 231 } 232 },1000); 233 self.waiting(); 234 } 235 /** 236 * 播放中处理 237 * @param {*} self 238 */ 239 function timeupdate(self) { 240 var ct = self.video.currentTime; 241 if(!self.duration) return; 242 self.feedData.play_time = ct*100/self.duration;//设置到住storage 243 // console.log("timeupdate"); 244 self.loadTimes>=2&&self.aPlay(); 245 var feed = self.feedData; 246 if(!feed.start&&ct>0){ 247 feed.hide = 0;//video is hide or show 248 feed.start = 1;//video is start ,should hide poster 249 } 250 self.vloading = 0; 251 self.play_btn = 0; 252 self.loadTimes = 0; 253 self.loaderror = 0; 254 if(!self.move&&ct+1>=self.duration/2){ 255 self.feedData.goodsMove = 1; 256 self.move = 1; 257 } 258 if(Math.round(ct)%3==0){ 259 self.wa("138146.35.1"); 260 } 261 if(!self.waDone&&Math.ceil(ct+1)>=self.duration){ 262 self.wa("138146.9.1"); 263 self.waDone = 1; 264 } 265 } 266 /** 267 * 处理视频和背景音乐 268 * @param {*} self 269 */ 270 function addEvent(self) { 271 self.$nextTick(function () { 272 self.video = self.$el.querySelector("video"); 273 var arry = ['stalled','playing', 'timeupdate', 'abort', 'error','durationchange','loadedmetadata','pause','x5videoexitfullscreen']; 274 arry.forEach(function (str) { 275 self.video.addEventListener(str,self['on'+str]); 276 }); 277 if(self.index==0){ 278 loadWX(function (env) { 279 if(env&&isAndroid) return; 280 self.play(); 281 }); 282 } 283 }); 284 var feed = self.feedData; 285 handleBGM(feed,self); 286 287 events.listen("touch_move",function (direct,i) { 288 handleMove(self,feed,direct,i); 289 }); 290 } 291 /** 292 * 处理滑动播放 293 * @param {*} self 294 * @param {*} feed 295 * @param {*} direct 296 * @param {*} i 297 */ 298 function handleMove(self,feed,direct,i) { 299 if(i==self.index){ 300 detailUtil.setShare(self.feedData); 301 if(!feed.playurl){ 302 feed.playurl = feed.videourl; 303 if(!feed.bgmurl_p&&feed.bgmurl){ 304 feed.bgmurl_p = feed.bgmurl; 305 self.audio.load(); 306 } 307 self.video.load(); 308 } 309 self.$nextTick(function () { 310 store.addPlayNum(feed.shareid); 311 if(self.audio&&!self.audioLoaded){ 312 var int = setInterval(function () { 313 if(self.audioLoaded){ 314 clearInterval(int); 315 self.play(1); 316 } 317 },100); 318 }else{ 319 self.play(1); 320 } 321 }); 322 } 323 //direct>0 则是下滑,页面出现上一个视频,则当前位置的下一个视频要暂停, 324 //direct<0则是上滑,页面要播放下一个视频了,则当前位置的上一个视频要暂停 325 if(self.index == i+(direct>0?1:-1)){ 326 self.pause(); 327 if(!self.loadedAll){ 328 feed.playurl = "";//如果是未加载完成,那么就不要加载了。 329 feed.start = 0; 330 feed.hide = 1; 331 } 332 if(!self.audioLoaded){ 333 feed.bgmurl_p = ""; 334 } 335 } 336 if(self.index>=i+7||self.index<=i-7){ 337 feed.maxHide = 1;//最大超过16个节点,则隐藏。 338 feed.playurl = "";//最大超过16个节点,则把其他视频干掉。 339 feed.start = 0; 340 feed.hide = 1; 341 }else{ 342 feed.maxHide = 0; 343 } 344 } 345 function loadWX(cb) { 346 if(device.scene=="weixin"){ 347 if(window.WeixinJSBridge){ 348 cb(1); 349 }else{ 350 document.addEventListener("WeixinJSBridgeReady", function() { 351 cb(1); 352 }); 353 } 354 }else{ 355 cb(); 356 } 357 } 358 /** 359 * 处理背景 360 * @param {*} feed 361 * @param {*} self 362 */ 363 function handleBGM(feed,self) { 364 //背景音乐 365 var bgm=feed.bgm; 366 if(bgm&&window.bgmlist&&bgmlist[bgm]){ 367 self.bg_name = bgmlist[bgm].bgmname; 368 feed.bgmurl = bgm+".mp3"; 369 if(self.index==0){ 370 feed.bgmurl_p = feed.bgmurl; 371 } 372 self.audio = self.$el.querySelector("audio"); 373 setPlay(self,0); 374 var t = setTimeout(function () {//超时处理 375 done(); 376 },4000); 377 loadWX(throuth); 378 function throuth(){ 379 self.audio.addEventListener("canplaythrough",function () { 380 done(); 381 }); 382 } 383 function done(){ 384 clearTimeout(t); 385 self.vloading = 0; 386 self.audioLoaded = 1; 387 !feed.start&&(setPlay(self,1));//还没播放,则吧播放按钮弹出来 388 } 389 390 }else{ 391 setPlay(self,1); 392 } 393 } 394 function compute(self) { 395 if(self.isCd) return; 396 var d = self.video.duration; 397 if (d>0) { 398 self.isCd = true; 399 self.duration = d; 400 self.checkLoading(); 401 } 402 } 403 function setPlay(self,f){ 404 self.play_btn = f; 405 self.vloading = !f; 406 } 407 function errors(self,msg) { 408 if(!self.video||!self.feedData.start) return; 409 self.loaderror++; 410 if(self.loaderror<=2){ 411 self.play(); 412 return; 413 } 414 setPlay(self,1); 415 msg += JSON.stringify(self.video.error)+","+self.video.src; 416 store.report(26,0,msg); 417 }
有H5项目需求欢迎联系我们 我们提供免费的项目评估报价
QQ:372900288
WX:Liuxiang0884