jQuery 鼠标事件不允许移动

jQuery Mouse Events not allowing to move

我正在创建一个简单的脚本,通过抓住(鼠标按下)面板之间的分隔线来调整面板大小(水平)。 (我在下面有一个片段要测试)

第一次使用效果很好,但有一个错误。

每当我按住鼠标左键抓住“#divider”并水平调整时,松开鼠标左键它就会起作用。但是如果第二步是:

(A) 立即再次抓住“#divider”并重复 => Nothing Happens。它要我点击屏幕来移动面板。

(B) 单击屏幕上的任意位置,然后抓住“#divider”并拖动 => 它工作正常。

我需要修复什么才能让用户无需先点击屏幕就可以抓住分隔线进行调整?

$(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>

我认为这就是您想要完成的。这会创建单独的 mousedown/mouseup 事件,将 down 变量设置为 true 或 false。这是在嵌套的 mousemove 上测试的,将 if($container.attr("data-inmove") == "1"){...} 替换为 if(down){...}

这是新脚本:

  // 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"});      
      }
    })
  });

这里是完整的工作代码:

$(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>

它不起作用的原因是您没有在 mousedown 处理程序中执行 e.preventDefault()。看到这个答案:

javascript-events-- 'mouseup' not firing after mousemove

确认只需添加一行即可使用您的代码,请参阅 this fiddle

PS:感谢@chris 提出了具有更好用户体验的替代解决方案,但我也想知道为什么这不起作用。