【问题标题】:onmouseup event does not work correctly to the slideronmouseup 事件对滑块无法正常工作
【发布时间】:2018-01-30 17:41:33
【问题描述】:

我创建了一个简单的 JS 滑块,它对 eventListener onmousedown 的点击做出反应。但是,如果您将运行下面的代码,您会看到,如果我们按住鼠标左键离开滚动区域scrollContainertoddler 不会被 eventListener onmouseup 正确停止。 toddler 将在下面松散滚动,我们将直接单击他。

需要什么-toddler 必须在我们释放鼠标左键时停止(在结束 eventListener onmousedown 之后)。

我将不胜感激。

		var scrollLine = document.getElementById('scrollBar');
		var scrollTog = document.getElementById('toddler');

		function letsMove(event) {

			var coordsHelp = getRealCoords(toddler);
			var shiftX = event.pageX - coordsHelp.left;

			getCoords(event);

  		function getRealCoords(toddler) {
  			var box = toddler.getBoundingClientRect();

  			return {
  				left: box.left + pageXOffset
  			}
  		};

			function getCoords(event) {
				var currentPosition = event.pageX - shiftX;

				if (currentPosition >= 300) {
					toddler.style.left = 300 + 'px';
				} else if (currentPosition <= 104) {
					toddler.style.left = 104 + 'px';
				} else {
					toddler.style.left = currentPosition + 'px';
				}
			};

			scrollContainer.onmousemove = function(event) {
				getCoords(event);
				console.log();
			};

			toddler.ondragstart = function() {
				return false;
			};

			toddler.onmouseup = function() {
		    scrollContainer.onmousemove = null;
		    scrollContainer.onmouseup = null;
		    toddler.onmouseup = null;
		    toddler.onmousemove = null;
		    return false;
			};
		}

		toddler.addEventListener( 'mousedown', letsMove );
<!DOCTYPE HTML>
<html>
<head>
	<meta charset="utf-8">
	<style>
		#scrollContainer {
			width:  400px;
			height: 200px;
			border:  1px solid grey;
			border-radius: 4px;
		}
		#scrollBar {
			width:  200px;
			height: 5px;
			background-color: grey;
			border:  1px solid grey;
			border-radius: 4px;
			margin-top: 24%;
			margin-left: 24%;
		}

		#toddler {
			width: 10px;
			height: 25px;
			position: absolute;
			margin-top: -11px;
			background-color: blue;
			border:  1px solid grey;
			border-radius: 2px;	
			cursor: pointer;		
		}

	</style>
</head>
<body>
	<div id="scrollContainer">
		<div id="scrollBar">
			<div id="toddler"></div>
		</div>
	</div>

	<script>
	</script>
  
</body>
</html>

【问题讨论】:

    标签: javascript html


    【解决方案1】:

    解决此问题的方法非常简单。当鼠标不在“幼儿”上方时,您没有触发onmouseup 的原因是因为鼠标不在“幼儿”上方。 (鼠标指针未触及的对象不会触发鼠标事件)。

    只需将侦听器更改为整个窗口(在“真实”代码中,您可能需要添加一个保护,以便您知道哪个滑块正在等待鼠标向上)。

    var scrollLine = document.getElementById('scrollBar');
    var scrollTog = document.getElementById('toddler');
    
    function letsMove(event) {
    
        var coordsHelp = getRealCoords(toddler);
        var shiftX = event.pageX - coordsHelp.left;
    
        getCoords(event);
    
        function getRealCoords(toddler) {
            var box = toddler.getBoundingClientRect();
    
            return {
                left: box.left + pageXOffset
            }
        };
    
        function getCoords(event) {
            var currentPosition = event.pageX - shiftX;
    
            if (currentPosition >= 300) {
                toddler.style.left = 300 + 'px';
            } else if (currentPosition <= 104) {
                toddler.style.left = 104 + 'px';
            } else {
                toddler.style.left = currentPosition + 'px';
            }
        };
    
        scrollContainer.onmousemove = function(event) {
            getCoords(event);
            console.log();
        };
    
        toddler.ondragstart = function() {
            return false;
        };
    
        /* toddler.onmouseup = function() { */
        window.onmouseup = function() {
            scrollContainer.onmousemove = null;
            scrollContainer.onmouseup = null;
            toddler.onmouseup = null;
            toddler.onmousemove = null;
            return false;
        };
    }
    
    toddler.addEventListener('mousedown', letsMove);
    <!DOCTYPE HTML>
    <html>
    <head>
    	<meta charset="utf-8">
    	<style>
    		#scrollContainer {
    			width:  400px;
    			height: 200px;
    			border:  1px solid grey;
    			border-radius: 4px;
    		}
    		#scrollBar {
    			width:  200px;
    			height: 5px;
    			background-color: grey;
    			border:  1px solid grey;
    			border-radius: 4px;
    			margin-top: 24%;
    			margin-left: 24%;
    		}
    
    		#toddler {
    			width: 10px;
    			height: 25px;
    			position: absolute;
    			margin-top: -11px;
    			background-color: blue;
    			border:  1px solid grey;
    			border-radius: 2px;	
    			cursor: pointer;		
    		}
    
    	</style>
    </head>
    <body>
    	<div id="scrollContainer">
    		<div id="scrollBar">
    			<div id="toddler"></div>
    		</div>
    	</div>
    
    	<script>
    	</script>
      
    </body>
    </html>

    【讨论】:

      【解决方案2】:

      一个解决方案可能是

      mouseout 事件绑定到特定目标区域,一旦鼠标离开该区域,您应该手动触发,或者在javascript 中我们应该说dispatch 事件mousedown,并且应该绑定到外部滑块容器,以便在单个页面上有多个滑块不会相互影响。一旦您超出容器范围,mouseout 事件将调度 toddler mousedown 事件。

      防止mouseout 在子元素悬停时触发的示例代码取自here,请参见下面的滑块。

      var scrollContainer = document.getElementById('scrollContainer');
      var scrollLine = document.getElementById('scrollBar');
      var toddler = document.getElementById('toddler');
      
      function letsMove(event) {
      
        var coordsHelp = getRealCoords(toddler);
        var shiftX = event.pageX - coordsHelp.left;
      
        getCoords(event);
      
        function getRealCoords(toddler) {
          var box = toddler.getBoundingClientRect();
      
          return {
            left: box.left + pageXOffset
          }
        };
      
      
      
        function getCoords(event) {
          var currentPosition = event.pageX - shiftX;
      
          if (currentPosition >= 300) {
            toddler.style.left = 300 + 'px';
          } else if (currentPosition <= 104) {
            toddler.style.left = 104 + 'px';
          } else {
            toddler.style.left = currentPosition + 'px';
          }
        };
      
      
      
        scrollContainer.onmousemove = function(event) {
          getCoords(event);
          console.log();
        };
      
        toddler.ondragstart = function() {
          return false;
        };
      
        toddler.onmouseup = function() {
          scrollContainer.onmousemove = null;
          scrollContainer.onmouseup = null;
          toddler.onmouseup = null;
          toddler.onmousemove = null;
          return false;
        };
      
      
      }
      
      function makeMouseOutFn(elem) {
        var list = traverseChildren(elem);
        return function onMouseOut(event) {
          var e = event.toElement || event.relatedTarget;
          if (!!~list.indexOf(e)) {
            return;
          }
      
          // handle mouse event here!
          if ('createEvent' in document) {
            // modern browsers, IE9+
            var e = document.createEvent('HTMLEvents');
            e.initEvent('mousedown', false, true);
            toddler.dispatchEvent(e);
          } else {
            // IE 8
            var e = document.createEventObject();
            e.eventType = 'mousedown';
            toddler.fireEvent('on' + e.eventType, e);
          }
        };
      }
      
      
      //quick and dirty BFS children traversal, Im sure you could find a better one                                        
      function traverseChildren(elem) {
        var children = [];
        var q = [];
        q.push(elem);
        while (q.length > 0) {
          var elem = q.pop();
          children.push(elem);
          pushAll(elem.children);
        }
      
        function pushAll(elemArray) {
          for (var i = 0; i < elemArray.length; i++) {
            q.push(elemArray[i]);
          }
      
        }
        return children;
      }
      toddler.addEventListener('mousedown', letsMove);
      
      scrollContainer.addEventListener('mouseout', makeMouseOutFn(scrollContainer), true);
      <!DOCTYPE HTML>
      <html>
      
      <head>
        <meta charset="utf-8">
        <style>
          #scrollContainer {
            width: 400px;
            height: 200px;
            border: 1px solid grey;
            border-radius: 4px;
          }
          
          #scrollBar {
            width: 200px;
            height: 5px;
            background-color: grey;
            border: 1px solid grey;
            border-radius: 4px;
            margin-top: 24%;
            margin-left: 24%;
          }
          
          #toddler {
            width: 10px;
            height: 25px;
            position: absolute;
            margin-top: -11px;
            background-color: blue;
            border: 1px solid grey;
            border-radius: 2px;
            cursor: pointer;
          }
        </style>
      </head>
      
      <body>
        <div id="scrollContainer">
          <div id="scrollBar">
            <div id="toddler"></div>
          </div>
        </div>
      
      </body>
      
      </html>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多