在另一个事件侦听器函数中定义的事件侦听器函数是否访问全局变量的副本?

时间:2016-06-19 16:59:52

标签: javascript html dom javascript-events mouseevent

我试图创建一个可以移动到任何位置的div,例如拖放功能。我使用了以下方法:

var songs = {};
songs.clickedM = 0;
$(".song-progress .current-position")[0].addEventListener("mousedown", function(down2) {
songs.clickedM = 1;
var intpos2 = down2.clientX;

$(".song-progress .current-position")[0].addEventListener( "mousemove", function(Dmove2) {

    if(songs.clickedM == 1) {           

        if (Dmove2.clientX <= $(".song-progress").offset().left) {
            $(".song-progress .current-position")[0].style.left = "0px";
            
        }
        else if( Dmove2.clientX >= ($(".song-progress").outerWidth() + $(".song-progress").offset().left)) {
            $(".song-progress .current-position")[0].style.left = ( $(".song-progress").outerWidth() - 14) + "px";
           
        }
        else {
            $(".song-progress .current-position")[0].style.left = (Dmove2.clientX - $(".song-progress").offset().left ) + "px";
           
        }
    }

});

});

$("body")[0].addEventListener("mouseup", function() {


songs.clickedM = 0;
   
});
.container {
  padding: 100px;
  width: 700px;
  height: 500px;
  background-color: lightgray;
}
.song-progress {
		position: absolute;
		top: 84px;
		right: 15px;
		height: 5px;
		width: calc(100% - 135px);
		background-color: white;
	}
 .current-progress{
		position: absolute;
		left: 0;
		width: 0px;
		height: 5px;
		background-color: #bbb;
	}
.current-time {
		position: absolute;
		bottom: 5px;
		font-size: 10px;
		left: 0;
		font-family: "Times New Roman"
	}
 .total-time {
		position: absolute;
		bottom: 5px;
		right: 0;
		font-size: 10px;
		font-family: "Times New Roman"
	}
 .current-position {
		height: 9px;
		width: 15px;
		background-color: #00cdff;
		position: absolute;
		top: -2.5px;
		left: 1px;
		cursor: pointer;
		border-radius: 5px;
	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
 <div class="song-progress">
                <div class="current-time">1:21</div>
                <div class="total-time">5:37</div>
                <div class="current-progress"></div>
                <div class="current-position"></div>
              </div>
              </div>

我注意到songs.clickedM永远不会变成0,即使鼠标键被释放也是如此。我的猜测是mousemove事件监听器是一个函数,它的作用就像一个函数闭包。当鼠标在第一次点击后第一次移动时,它会访问songs.clickedM的副本而不是原始副本。它不知道原始变量songs.clickedM实际上已更改为0

  

如果未按下该键,如何为mousemove事件侦听器设置songs.clickedM 0的值?

1 个答案:

答案 0 :(得分:1)

  

我的猜测是mousemove事件监听器是一个函数,就像一个函数闭包。

它不像关闭一样行事一个闭包。 : - )

  

当鼠标第一次点击后第一次移动时,它会访问songs.clickedM的副本,而不是原始副本。它不知道原始变量songs.clickedM实际上已更改为0

没有。闭包可以访问它们关闭的变量,而不是它们关闭的变量的副本。即使他们收到了副本,在这种情况下关闭的变量也是songs,它只是对象的引用;它的副本仍将引用相同的对象,具有相同的clickedM属性。你所有的偶数处理程序都在它所引用的对象上使用相同的 songs变量和相同的clickedM属性。问题出在其他地方。

在那里需要调试,但显示的一个红色标志是代码在元素上按下鼠标时每次添加一个新的mousemove处理程序,即使它之前已被添加。所以那些mousemove处理程序开始堆叠。