jquerymouseup

jQuery Mouse Events not allowing to move


I'm creating a simple script that adjusts the panel sizes (horizontally) by grabbing (mousedown) the divider in between the panels. (I have a snippet to test below)

It works great the first time, but it has a bug.

Whenever i Grab the "#divider" by holding down left mouse button and adjust horizontally, release left-mouse button it works. But if the second step is to:

(A) Immediately grab the "#divider" again and repeat => Nothing Happens. It wants me to click on the screen to move the panel.

(B) Click anywhere on the screen THEN grab the "#divider" and drag => It works fine.

What do I need to fix so that the user can grab the divider and adjust without having to click the screen first?

$(function() {
	
   //Store the container object in cache
   let $container = $("#container");
	
    //When the user holds the mouse down on the divider, identify the x-coordinate and store in the container. Also note that we are trying to adjust the panel ("data-inmove" = "1")
	$(document).on("mousedown", "#divider", function(e) {
		$container.attr({"data-start":e.pageX, "data-inmove":"1"});
	});
	
    //When the mouse has been released, check to see if we have an "inmove" variable equal to "1".
    // if so, then change the panel width. Finally reset the variables
	$(document).on("mouseup", function(e) {
		if ($container.attr("data-inmove") == "1") {			
			$("#leftPanel").css("flex", "0 0 " + (e.pageX-3) + "px");
		}
		$container.attr({"data-start":"0", "data-end":"0", "data-inmove":"0"});
	});
	
});
#container .col {
  padding-left:0px !important;
  padding-right:0px !important;
}

#container {
  width:95%;
  margin:10px auto;
  border:1px solid #929292;
  min-height:300px;
  position:relative;
}

#leftPanel {
  flex:0 0 200px;
  background-color:grey;
}

#divider {
  flex:0 0 3px;
  background-color:#333;
  cursor:e-resize;
}

#rightPanel {
  background-color:#fff;
}
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>

  
  
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

<strong>Grab the black bar in between the panels. Adjust it horizontally. If you try it a second time (without clicking anywhere else), it won't work. It will wait until you click the page instead. Why does it do this?</strong><br/>

<div class="row" id="container" data-start="0" data-end="0" data-inmove="0">
    <div class="col" id="leftPanel">
      
    </div>
    
   <div class="col" id="divider"></div>
    <div class="col" id="rightPanel">
      
    </div>
  </div>


Solution

  • I think this is what you are trying to accomplish. This creates separate mousedown/mouseup events which set a down variable to true or false. This is tested on a nested mousemove instead, replacing the if($container.attr("data-inmove") == "1"){...} with if(down){...}.

    This is the new script:

      // Creates a boolean if mouse is down
      var down = false;
      // Use mouse events to change it
      $(document).mousedown(function() {
        down = true;
      }).mouseup(function() {
        down = false;  
      }); 
    
      $(document).on("mousedown", "#divider", function(e) {
        $container.attr({"data-start":e.pageX, "data-inmove":"1"});
        $(document).mousemove(function(e){
          //check if down or not before changing properties
          if(down){
            $("#leftPanel").css("flex", "0 0 " + (e.pageX-3) + "px");
            $container.attr({"data-start":"0", "data-end":"0", "data-inmove":"0"});      
          }
        })
      });
    

    And here is the full working code:

    $(function() {
    
      let $container = $("#container");
    
      // Creates a boolean if mouse is down
      var down = false;
      // Use mouse events to change it
      $(document).mousedown(function() {
        down = true;
      }).mouseup(function() {
        down = false;  
      });  
    
      $(document).on("mousedown", "#divider", function(e) {
        $container.attr({"data-start":e.pageX, "data-inmove":"1"});
        $(document).mousemove(function(e){
    
          //check if down or not before changing properties
          if(down){
            $("#leftPanel").css("flex", "0 0 " + (e.pageX-3) + "px");
            $container.attr({"data-start":"0", "data-end":"0", "data-inmove":"0"});      
          }
        })
      });
    
    });
    #container .col {
      padding-left:0px !important;
      padding-right:0px !important;
    }
    
    #container {
      width:95%;
      margin:10px auto;
      border:1px solid #929292;
      min-height:300px;
      position:relative;
    }
    
    #leftPanel {
      flex:0 0 200px;
      background-color:grey;
    }
    
    #divider {
      flex:0 0 3px;
      background-color:#333;
      cursor:e-resize;
    }
    
    #rightPanel {
      background-color:#fff;
    }
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    
    
    
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    
    <strong>Grab the black bar in between the panels. Adjust it horizontally. If you try it a second time (without clicking anywhere else), it won't work. It will wait until you click the page instead. Why does it do this?</strong><br/>
    
    <div class="row" id="container" data-start="0" data-end="0" data-inmove="0">
      <div class="col" id="leftPanel">
    
      </div>
    
     <div class="col" id="divider"></div>
      <div class="col" id="rightPanel">
    
      </div>
    </div>