拖拽进度条按钮函数的几个小问题

来源:4-8 video-javascript(5)

键盘f11

2020-11-03 17:48:53

# 具体遇到的问题

http://img.mukewang.com/climg/5fa1146c09c4545303570097.jpg

http://img.mukewang.com/climg/5fa1146c09b1d97a01890122.jpg

老师,您好,我想咨询一下关于document.onmousemove = function(e)函数

var needX = ev.clientX - l;   var l = ev.clientX - this.offsetLeft; 那么是否可以理解为

var needX=this.offsetLeft; ?  needX是滚动圆圈到父类最左侧的距离

但是如果我直接定义var needX=this.offsetLeft; 是取不到这个数值的,会显示undefined 这个是因为什么原因呢? 为什么在定义l变量的时候就可以取到呢? var l = ev.clientX - this.offsetLeft;这是可以取到this.offsetLeft;

是什么原因呢?



# 报错信息的截图
http://img.mukewang.com/climg/5f6c317509cb1b8321630370.jpg# 相关课程内容截图

# 尝试过的解决思路和结果
LineNode.style.width = (CrlNode.offsetLeft+9)/LoadNode.offsetWidth*100 + '%';

老师,针对于这段代码我尝试着理解了一下

http://img.mukewang.com/climg/5fa11cac094032ec02590212.jpg

http://img.mukewang.com/climg/5fa11cad094b9d6503110098.jpg

指的是当前进度条的宽度=进度条的按钮数值(距离父容器最左侧的距离+9),为什么是+9呢?是不是应该是8.5呢,因为整个滑动圆圈的宽度是17px,是因为四舍五入的原因呢?   

LoadNode.offsetWidth为整个父容器的宽度,是否为上述截屏所示,,如果不算上margin的数值的话,

应该是整个进度条的宽度的

那假设圆圈滚动条到达最右侧的时候,是否为CrlNode.offsetLeft==LoadNode.offsetWidth两者的数值上是相等的呢?那么CrlNode.offsetLeft如果加上9的话不应该是比LoadNode.offsetWidth大么? 这段代码应该是我理解错了,如何去理解呢?

​# 粘贴全部相关代码,切记添加代码注释(请勿截图)


<!doctype html> 

<html> 

<head> 

    <meta charset="utf-8"> 

    <title></title> 

    <style type="text/css">

*{margin: 0;padding: 0;list-style: none;} 

.outerNode{width: 540px;height: 332px;position: absolute;left: 50%;top: 50%;margin: -166px 0 0 -270px;box-shadow: 0 0 4px #5b606d;}  

.outerNode .videoNode{

width: 540px;height: 305px;float: left;

background: black;

}

.outerNode .controlsNode{

width: 540px;height: 27px;float: left;background: url(images/ctrs_bg.gif) repeat-x;

}


.outerNode .controlsNode .playNode{

float: left;width: 15px;height: 17px;margin: 6px 0 0 14px;

background: url(images/playNode.png) no-repeat;cursor: pointer;

}

.outerNode .controlsNode .pauseNode{

float: left;width: 15px;height: 17px;margin: 6px 0 0 14px;

background: url(images/pause.png) no-repeat;cursor: pointer;

}



.outerNode .controlsNode .loadNode{width: 267px;height: 10px;margin: 9px 0 0 14px;float: left;background: url(images/load_bg.png) repeat-x;position: relative;}

.outerNode .controlsNode .loadNode .lineNode{

width: 0%;height: 7px;position: absolute;left: 0;top: 1px;

background: url(images/line_bg.png) repeat-x;


}

.outerNode .controlsNode .loadNode .lineNode .lineRight{

width: 2px;height: 100%;position: absolute;right: 0;top: 0;

background: url(images/line_r_bg.png) no-repeat;

}


.outerNode .controlsNode .loadNode .loadLeft{

height: 100%;width:3px ;position: absolute;left: 0;top: 0;

background: url(images/left_bg.png) no-repeat;z-index: 4;

}

.outerNode .controlsNode .loadNode .loadRight{

height: 100%;width:3px ;position: absolute;right: 0;top: 0;

background: url(images/right_bg.png) no-repeat;

}

.outerNode .controlsNode .loadNode .crlNode{width: 17px;height: 17px;background: url(images/crl_bg.png);position: absolute;left: -8.5px;top: -3.5px;cursor: pointer;z-index: 5;}


.outerNode .controlsNode .timeNode{

float: left;width: 75px;height: 10px;margin: 9px 0 0 9px;

}

.outerNode .controlsNode .timeNode span{font-size:10px;float: left;line-height: 10px;color: white; }

.outerNode .controlsNode .volumeNode{

width: 17px;height: 16px;float: left;margin: 5px 0 0 6px;

background: url(images/volume_bg.png);

}

.outerNode .controlsNode .volumeLine{

height: 8px;width: 61px;float: left;margin: 10px 0 0 4px;

background: url(images/volumeLine_bg.png) repeat-x;position: relative; 

}

.outerNode .controlsNode .volumeLine .v_left{

width: 3px;height:100%;position: absolute;left: 0;top: 0;background: url(images/v_left.png) no-repeat;

}

.outerNode .controlsNode .volumeLine .v_right{

width: 3px;height:100%;position: absolute;right: 0;top: 0;background: url(images/v_right.png) no-repeat;

}

.outerNode .controlsNode .volumeLine .v_DragNode{width: 15px;height: 13px;position: absolute;left: -2.5px;top: -3.5px;background: url(images/vo_d.png) no-repeat;cursor: pointer;}

.outerNode .controlsNode .fullNode{

width:15px;height:17px;float: left;margin: 6px 0 0 35px;

background: url(images/full_bg.png) no-repeat;cursor: pointer;

transition: 0.7s;

}

.outerNode .controlsNode .fullNode:hover{

background: url(images/full_hover_bg.png) no-repeat;

}


    </style>


</head>

<body>

<!-- 最外层的元素 -->

<div class='outerNode'>

<!-- video元素 -->

<video class='videoNode' src='data/imooc.mp4' poster="data/poster.jpg"></video>

<!-- 控制器的元素 -->

<div class='controlsNode'>

<!-- 控制播放暂停的按钮 -->

<div class='playNode'></div>

<!-- video的进度条 -->

<div class='loadNode'>

<div class='loadLeft'></div>

<div class='loadRight'></div>

<!-- 拖动进度条的按钮 -->

<div class='crlNode'></div>

<!-- 真正的进度条 -->

<div class='lineNode'>

<div class='lineRight'></div>

</div>

</div>

<!-- 时间的元素 -->

<div class='timeNode'>

<span class='now'>00:00</span>

<span> - </span>

<span class='all'>4:30</span>

</div>

<!-- 声音的标志 -->

<div class='volumeNode'></div>

<!-- 声音的条 -->

<div class='volumeLine'>

<div class='v_left'></div>

<div class='v_right'></div>

<div class='v_DragNode'></div>

</div>

<!-- 全屏的按钮 -->

<div class='fullNode'></div>

</div>

</div>

<script type="text/javascript">

//播放暂停的控制

//PlayNode 就是播放器按钮

//VideoNode 就是播放器

//PlayBln 控制暂停播放的布尔值

//FullNode 全屏按钮

//nowNode 当前时间

//allNode 视频的全部时间

//LineNode 当前的进度条

//CrlNode 进度条按钮

//LoadNode 进度条外面的元素

var PlayNode = document.getElementsByClassName('playNode')[0],

VideoNode = document.getElementsByClassName('videoNode')[0],

FullNode = document.querySelector('.fullNode'),

nowNode = document.querySelector('.now'),

allNode = document.querySelector('.all'),

LineNode = document.querySelector('.lineNode'),

CrlNode = document.querySelector('.crlNode'),

LoadNode = document.querySelector('.loadNode'),

PlayBln = true;


//播放、暂停的事件

PlayNode.onclick = function(){

//传统的通过布尔值去改变classname的方法

PlayBln = !PlayBln;

if(PlayBln == false){

this.className = 'pauseNode';

VideoNode.play();


}

else{

this.className = 'playNode';

VideoNode.pause();

}

//console.log(1);

//console.log(PlayNode.classList);

//可以使用classList.toggle方法来切换

//this.classList.toggle('pauseNode');

};


//全屏按钮的事件

FullNode.onclick = function(){

if(VideoNode.webkitRequestFullscreen){

VideoNode.webkitRequestFullscreen();

}

else if(VideoNode.mozRequestFullScreen){

VideoNode.mozRequestFullScreen();

}

else{

VideoNode.requestFullscreen();

}

};


//视频的总时间的计算

/*

setTimeout(function(){

allNode.innerHTML = VideoNode.duration;


},100);

*/

//解决了 上来时间的NAN的问题

VideoNode.addEventListener('canplay',function(){

//allNode.innerHTML = VideoNode.duration;

var needTime = parseInt(VideoNode.duration);

var  s = needTime%60;

var  m = parseInt(needTime / 60);

var timeNum = toDou(m)+':'+toDou(s);

allNode.innerHTML = timeNum;

},false);


//解决 时间不足10 的一个问题

function toDou(time){

return time<10?'0'+time:time;

}

//当视频播放的时候 需要当前的时间动起来

VideoNode.addEventListener('timeupdate',function(){

//看一眼目前的 百分比进度

//console.log(VideoNode.currentTime/VideoNode.duration*100);

LineNode.style.width = VideoNode.currentTime/VideoNode.duration*100+'%';


//console.log(LineNode.offsetWidth)

CrlNode.style.left = LineNode.offsetWidth - 8.5 + 'px'


var needTime = parseInt(VideoNode.currentTime);

var  s = needTime%60;

var  m = parseInt(needTime / 60);

var timeNum = toDou(m)+':'+toDou(s);

nowNode.innerHTML = timeNum;

},false);

//拖拽进度条按钮

CrlNode.onmousedown = function(e){

var ev = e || event;

var l = ev.clientX - this.offsetLeft;

VideoNode.pause();

document.onmousemove = function(e){

var ev = e || event;

var needX = ev.clientX - l;

//var needX=this.offsetLeft;

var maxX = LoadNode.offsetWidth - 8.5;

console.log(needX);

//needX = needX < -8.5 ? -8.5 : needX;

//needX = needX > maxX ? maxX : needX;

CrlNode.style.left = needX + 'px';

LineNode.style.width = (CrlNode.offsetLeft+9)/LoadNode.offsetWidth*100 + '%';

};

document.onmouseup = function(){

document.onmousemove = document.onmouseup = null;

VideoNode.currentTime = VideoNode.duration * (CrlNode.offsetLeft+9)/LoadNode.offsetWidth;

//console.log((CrlNode.offsetLeft+9)/LoadNode.offsetWidth);

//console.log()

//VideoNode.play();

//PlayBln = false;

//className = 'pauseNode';

if(PlayBln == false){

//console.log(1);

PlayNode.className = 'pauseNode';

VideoNode.play();

}

else{

//console.log(2);

PlayNode.className = 'playNode';

VideoNode.pause();

}

};

};

</script>

</body>

</html>

在这里输入代码,可通过选择【代码语言】突出显示

写回答

1回答

好帮手慕慕子

2020-11-03

同学你好,对于你的问题解答如下:

1、如下图所示,不可以直接写var needX = this.offsetLeft,因为鼠标按下和拖动过程中ev.clientX值是不一样的,不可以直接消除。

http://img.mukewang.com/climg/5fa12d99098468de06940113.jpg

可以打印下查看效果:

http://img.mukewang.com/climg/5fa12d4109376af707850350.jpg


http://img.mukewang.com/climg/5fa12cdd0991412412190574.jpg

2、因为onmousemove事件是绑定在document对象上的,所以移动过程中的this是指向document对象,所以直接使用this.offsetLef获取的结果是undefined

http://img.mukewang.com/climg/5fa12f1c0965bae407110274.jpg

测试结果this确实是指向document对象

http://img.mukewang.com/climg/5fa12f2a09d1c22f04880433.jpg

3、因为var l = ev.clinetX - this.offsetLeft 是在onmousedown事件下定义的,此时的this指向进度条拖拽按钮,所以可以获取到对应的offsetLeft属性值。

http://img.mukewang.com/climg/5fa12fdb0992400608610172.jpg

4、可能由于系统和浏览器解析问题,视频中老师打印Crlnode.offsetLeft的初始值为9,所以老师就根据实际打印出的结果计算了。同学自己练习时,可以先获取Crlnode初始的offsetLeft值,保存下来,然后直接就使用这个值进行计算就可以了。示例:由于获取的值是负值,所以就需要调整减去这个值。

http://img.mukewang.com/climg/5fa1324809e03c0f13060723.jpg

5、LoadNode.offsetWidth是整个父容器的宽度,是同学截图所示的内容。

6、同学理解是没有问题的,至于老师讲解时为什么加上9,可以参考老师的第4条解析,

CrlNode.offsetLeft获取的是按钮距离它父元素的值,由于一开始按钮在父元素的左侧显示,此时的offsetLeft是赋值,所以需要减去一开始的offsetLeft值,在按钮移动到最右侧时,才等于整个父容器的宽度。

可以输出测试下结果结果,如下所示:

http://img.mukewang.com/climg/5fa133920904112d10310686.jpg

按钮移动到最后,两者的值是相等的

http://img.mukewang.com/climg/5fa133c509d2d97e13180873.jpg

祝学习愉快~

0

0 学习 · 6815 问题

查看课程