如何设置jQuery拖拽最小/max-left和min/max-right

时间:2022-02-12 07:22:37

I made a copy of JSbin for practice, JSbin link here, actual site link here.

我复制了JSbin用于实践,这里是JSbin链接,这里是实际的站点链接。

This is just a practice for making the front-end of websites as I just started learning web dev little over a week ago. You can put in html, css and javascript in the editboxes, and a page spit out in Output just like the actual JSbin.

这只是做网站前端的一种实践,因为我一周前才开始学习web开发。您可以在editbox中输入html、css和javascript,然后输出一个页面,就像实际的JSbin一样。

But the problem is that you can resize the divs pass other divs.

但是问题是你可以调整divs的大小来传递其他divs。

My idea to prevent this from happening is:
1. get the editboxes' current positions
2. store the left/right position of the editbox if resized to 10% window width
3. set the min/max left and right for the draggable div

我的想法是:1。获取编辑框的当前位置2。如果修改为10%窗口宽度3,则存储editbox的左/右位置。为draggable div设置最小/最大值

And hence the question. How do I set the max-left/right for the draggable.

因此这个问题。如何为可拖动设置max-left/right。

Also, any idea on why the draggable before Output div is diificult to drag to the right.

另外,任何关于为什么在输出div之前拖拽的想法都是要拖到右边的。

Edit: How the site is structured. When you drag the .drag (.resize in my JSbin code), it changes its left and right div's left and right. And the draggables are contained in the #main's div.

编辑:网站的结构。拖拽。在我的JSbin代码中调整大小),它改变它的左和右div的左和右。并且可拖拽属性包含在#main的div中。

<div id="main>
  <div id="HTML"></div>
                
  <div class="drag"></div> //drag this left and right to change the right of the HTML and left of CSS
                     
  <div id="CSS"></div>
               
  <div class="drag"></div> //drag this left and right to change the right of the Css and left of JavaScript
                     
  <div id="JavaScript"></div>
                      
  <div class="drag"></div> //drag this left and right to change the right of the JavaScript and left of Output
                     
  <div id="Output"></div>
</div>

3 个解决方案

#1


2  

By taking advantage of jQuery Ui's built in draggable event which gives us position information and also allows us to set position on drag.

利用jQuery Ui在可拖拽事件中内置的位置信息,我们可以在拖拽中设置位置。

I came up with the following solution:

我想到了以下解决方案:

var dragDistance = 100;

$(".resize").draggable({
  axis: "x", 
  containment: "parent",
  drag: function( event, ui){ 

    ui.position.left = Math.min( ui.position.left,  ui.helper.next().offset().left + ui.helper.next().width()-dragDistance); 
    ui.position.left = Math.max(ui.position.left, ui.helper.prev().offset().left + dragDistance);

   resize();

  }
});

I removed your onDrag function in the process so it wouldn't interfere.

我在进程中删除了onDrag函数,这样它就不会干扰。

See the bin here:

看到箱子:

JSBin

JSBin

NOTES:

注:

  1. I haven't looked into it and maybe its just a JSBin issue because I can't reproduce it in your live site. But if the boundary lines disappear while you are dragging the code won't work. You'll probably have to increase the drag distance to the point where the lines don't disappear while dragging.

    我还没有研究过它,可能只是一个JSBin问题因为我不能在你的实时站点中复制它。但是,如果在拖拽代码时边界线消失了,那么代码就不能工作了。您可能需要增加拖拽距离,使线在拖拽时不会消失。

  2. You may notice you have difficulty dragging the Output box that seems to be caused by the Iframe you have inside. If I comment out the IFrame I can drag it just fine. I haven't looked for a solution but perhaps experiment with some padding or margins so that the Iframe is not pegged so closely against the border. Or maybe if you detached it from the DOM while dragging that would fix it.

    您可能注意到您在拖拽输出框时遇到了困难,这似乎是由内部的Iframe造成的。如果我注释掉IFrame,我可以拖拽它。我还没有寻找解决方案,但也许可以尝试使用一些填充或边距,这样Iframe就不会被如此紧密地绑定到边框上。或者,如果您在拖拽时将它从DOM中分离出来,就可以修复它。

#2


1  

Use containment

使用容器

Constrains dragging to within the bounds of the specified element or region.

限制拖动到指定元素或区域的范围内。

For Eg:

如:

$( ".selector" ).draggable({
  containment: "parent"
});

Click Here For a Demo

点击这里观看演示。

#3


0  

You could manually keep track of the position of each of the windows in the dragging() function, and only call the resize() method if they don't overlap:

您可以手动跟踪拖动()函数中每个窗口的位置,如果它们不重叠,只调用resize()方法:

function dragging(event) {
  var CSS_left = parseInt($("#CSS").css("left"));
  var JavaScript_left = parseInt($("#JavaScript").css("left"));
  var Output_left = parseInt($("#Output").css("left"));
  var offset = 100;
  var checkOverlap1 = $(event.target).is("#1") 
                     && event.clientX + offset <= JavaScript_left 
                     && event.clientX >= offset;
  var checkOverlap2 = $(event.target).is("#2") 
                     && event.clientX + offset <= Output_left 
                     && event.clientX - offset >= CSS_left;
  var checkOverlap3 = $(event.target).is("#3") 
                     && event.clientX - offset >= JavaScript_left 
                     && event.clientX <= codeboxWidth - offset;

  if (checkOverlap1 || checkOverlap2 || checkOverlap3) {
    resize(event);
  }
}

Here's the complete example - I also refactored/simplified your "resize" function.

下面是完整的示例——我还重构/简化了“调整大小”函数。

var codeboxWidth = $("#codebox").width();

$(document).ready(function() {
  $("#codebox").height($(window).height() - $("#topbar").height());
  $(".content").height($("#codebox").height());
  $(".editbox").height($(".content").height() - $(".contentheader").height());
  $("#HTML").css("left", 0);
  $("#HTML").css("right", "75%");
  $("#CSS").css("left", "25%");
  $("#CSS").css("right", "50%");
  $("#JavaScript").css("left", "50%");
  $("#JavaScript").css("right", "25%");
  $("#Output").css("left", "75%");
  $("#Output").css("right", 0);
});

function resize(event) {
  if ($(event.target).is("#1")) {
    $("#CSS").css("left", event.clientX);
    $("#HTML").css("right", codeboxWidth - event.clientX);
  }
  if ($(event.target).is("#2")) {
    $("#JavaScript").css("left", event.clientX);
    $("#CSS").css("right", codeboxWidth - event.clientX);

  }
  if ($(event.target).is("#3")) {
    $("#Output").css("left", event.clientX);
    $("#JavaScript").css("right", codeboxWidth - event.clientX);
  }
}

$(".resize").draggable({
  axis: "x"
});

function dragging(event) {
  var CSS_left = parseInt($("#CSS").css("left"));
  var JavaScript_left = parseInt($("#JavaScript").css("left"));
  var Output_left = parseInt($("#Output").css("left"));
  var offset = 100;
  var checkOverlap1 = $(event.target).is("#1") 
                      && event.clientX + offset <= JavaScript_left 
                      && event.clientX >= offset;
  var checkOverlap2 = $(event.target).is("#2") 
                      && event.clientX + offset <= Output_left 
                      && event.clientX - offset >= CSS_left;
  var checkOverlap3 = $(event.target).is("#3") 
                      && event.clientX - offset >= JavaScript_left 
                      && event.clientX <= codeboxWidth - offset;

  if (checkOverlap1 || checkOverlap2 || checkOverlap3) {
    resize(event);
  }
}
body {
  margin: 0;
  padding: 0;
  overflow-y: hidden;
  overflow-x: hidden;
  background: #F7F7F7;
  font-family: Arial;
}
#topbar {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 35px;
  background: #EEEEEE;
  position: relative;
}
h2 {
  margin: 2px 0 0 0;
  padding: 0;
  float: left;
  position: absolute;
}
#control {
  width: 100%;
  margin: 8px 0 0 0;
  padding: 0;
  position: absolute;
  text-align: center;
}
.option {
  margin: 0 -5px 0 0;
  padding: 5px 10px 5px 10px;
  text-align: center;
  border-top: 1px solid #CCC;
  border-bottom: 1px solid #CCC;
  border-left: 1px solid #CCC;
  text-decoration: none;
  font-size: 0.9em;
  color: black;
}
.option:first-child {
  border-bottom-left-radius: 5px;
  border-top-left-radius: 5px;
}
.option:last-child {
  border-right: 1px solid #CCC;
  border-bottom-right-radius: 5px;
  border-top-right-radius: 5px;
}
.option:hover {
  background: #dee5e5;
}
.opactive {
  background: #EBF3FF;
}
.opinactive {
  background: 0;
}
.active {
  display: block;
}
.inactive {
  display: none;
}
#codebox {
  margin: 0;
  padding: 0 width: 100%;
  position: static;
  top: 35px;
  background: white;
}
.content {
  margin: 0;
  padding: 0;
  min-width: 10%;
  max-width: 100%;
  position: absolute;
  float: left;
  color: #6DCAFC;
  background: #F7F7F7;
  overflow: hidden;
}
.resize {
  top: 35px;
  bottom: 0px;
  width: 1px;
  margin-left: 0;
  height: 100%;
  right: auto;
  opacity: 0;
  position: absolute;
  cursor: ew-resize;
  border-left-width: 1px;
  border-left-style: solid;
  border-left-color: rgba(218, 218, 218, 0.498039);
  z-index: 99999;
  background: #666;
}
.contentheader {
  margin: 0;
  padding: 0;
  background: transparent;
  position: relative;
}
.selectedcontent {
  background: white;
}
.contentbox {
  width: 100%;
  height: 100%;
  background: transparent;
  position: relative;
  box-sizing: border-box;
  border-right: 1px solid darkgrey;
  overflow: hidden;
}
.editbox {
  width: 100%;
  height: 100%;
  background: transparent;
  overflow: hidden;
}
.textareabox {
  background: transparent;
  min-width: 100%;
  max-width: 100%;
  min-height: 100%;
  max-height: 100%;
  border: none;
  outline: none;
  resize: none;
}
<!DOCTYPE html>
<html>

<head>
  <title>Project 04</title>
  <link rel="stylesheet" type="text/css" href="styles.css">
  <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">

</head>

<body>
  <div id="topbar">
    <h2>Code Runner</h2>
    <div id="control">
      <a href="#" class="option opactive">HTML</a>
      <a href="#" class="option opactive">CSS</a>
      <a href="#" class="option opactive">JavaScript</a>
      <a href="#" class="option opactive">Output</a>
    </div>
  </div>

  <div id="codebox">
    <div id="HTML" class="content active">
      <div class="contentbox">
        <div class="contentheader">HTML</div>
        <div class="editbox" id="HTMLeditbox">
          <textarea id="HTMLcode" class="textareabox"></textarea>
        </div>
      </div>
    </div>

    <div class="resize active" id="1" style="left: 25%" ondrag="dragging(event)"></div>

    <div id="CSS" class="content active">
      <div class="contentbox">
        <div class="contentheader">CSS</div>
        <div class="editbox" id="CSSeditbox">
          <textarea id="CSScode" class="textareabox"></textarea>
        </div>
      </div>
    </div>

    <div class="resize active" id="2" style="left: 50%" ondrag="dragging(event)"></div>

    <div id="JavaScript" class="content active">
      <div class="contentbox">
        <div class="contentheader">JavaScript</div>
        <div class="editbox" id="JavaScripteditbox">
          <textarea id="JavaScriptcode" class="textareabox"></textarea>
        </div>
      </div>
    </div>

    <div class="resize active" id="3" style="left: 75%" ondrag="dragging(event)"></div>

    <div id="Output" class="content active">
      <div class="contentbox">
        <div class="contentheader">Output</div>
        <div class="editbox" id="Outputbox">

        </div>
      </div>
    </div>
  </div>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>


  <script type="text/javascript" src="jscript.js"></script>
</body>

</html>

Here's a JSBin based on your example.

这是一个基于您的示例的JSBin。

#1


2  

By taking advantage of jQuery Ui's built in draggable event which gives us position information and also allows us to set position on drag.

利用jQuery Ui在可拖拽事件中内置的位置信息,我们可以在拖拽中设置位置。

I came up with the following solution:

我想到了以下解决方案:

var dragDistance = 100;

$(".resize").draggable({
  axis: "x", 
  containment: "parent",
  drag: function( event, ui){ 

    ui.position.left = Math.min( ui.position.left,  ui.helper.next().offset().left + ui.helper.next().width()-dragDistance); 
    ui.position.left = Math.max(ui.position.left, ui.helper.prev().offset().left + dragDistance);

   resize();

  }
});

I removed your onDrag function in the process so it wouldn't interfere.

我在进程中删除了onDrag函数,这样它就不会干扰。

See the bin here:

看到箱子:

JSBin

JSBin

NOTES:

注:

  1. I haven't looked into it and maybe its just a JSBin issue because I can't reproduce it in your live site. But if the boundary lines disappear while you are dragging the code won't work. You'll probably have to increase the drag distance to the point where the lines don't disappear while dragging.

    我还没有研究过它,可能只是一个JSBin问题因为我不能在你的实时站点中复制它。但是,如果在拖拽代码时边界线消失了,那么代码就不能工作了。您可能需要增加拖拽距离,使线在拖拽时不会消失。

  2. You may notice you have difficulty dragging the Output box that seems to be caused by the Iframe you have inside. If I comment out the IFrame I can drag it just fine. I haven't looked for a solution but perhaps experiment with some padding or margins so that the Iframe is not pegged so closely against the border. Or maybe if you detached it from the DOM while dragging that would fix it.

    您可能注意到您在拖拽输出框时遇到了困难,这似乎是由内部的Iframe造成的。如果我注释掉IFrame,我可以拖拽它。我还没有寻找解决方案,但也许可以尝试使用一些填充或边距,这样Iframe就不会被如此紧密地绑定到边框上。或者,如果您在拖拽时将它从DOM中分离出来,就可以修复它。

#2


1  

Use containment

使用容器

Constrains dragging to within the bounds of the specified element or region.

限制拖动到指定元素或区域的范围内。

For Eg:

如:

$( ".selector" ).draggable({
  containment: "parent"
});

Click Here For a Demo

点击这里观看演示。

#3


0  

You could manually keep track of the position of each of the windows in the dragging() function, and only call the resize() method if they don't overlap:

您可以手动跟踪拖动()函数中每个窗口的位置,如果它们不重叠,只调用resize()方法:

function dragging(event) {
  var CSS_left = parseInt($("#CSS").css("left"));
  var JavaScript_left = parseInt($("#JavaScript").css("left"));
  var Output_left = parseInt($("#Output").css("left"));
  var offset = 100;
  var checkOverlap1 = $(event.target).is("#1") 
                     && event.clientX + offset <= JavaScript_left 
                     && event.clientX >= offset;
  var checkOverlap2 = $(event.target).is("#2") 
                     && event.clientX + offset <= Output_left 
                     && event.clientX - offset >= CSS_left;
  var checkOverlap3 = $(event.target).is("#3") 
                     && event.clientX - offset >= JavaScript_left 
                     && event.clientX <= codeboxWidth - offset;

  if (checkOverlap1 || checkOverlap2 || checkOverlap3) {
    resize(event);
  }
}

Here's the complete example - I also refactored/simplified your "resize" function.

下面是完整的示例——我还重构/简化了“调整大小”函数。

var codeboxWidth = $("#codebox").width();

$(document).ready(function() {
  $("#codebox").height($(window).height() - $("#topbar").height());
  $(".content").height($("#codebox").height());
  $(".editbox").height($(".content").height() - $(".contentheader").height());
  $("#HTML").css("left", 0);
  $("#HTML").css("right", "75%");
  $("#CSS").css("left", "25%");
  $("#CSS").css("right", "50%");
  $("#JavaScript").css("left", "50%");
  $("#JavaScript").css("right", "25%");
  $("#Output").css("left", "75%");
  $("#Output").css("right", 0);
});

function resize(event) {
  if ($(event.target).is("#1")) {
    $("#CSS").css("left", event.clientX);
    $("#HTML").css("right", codeboxWidth - event.clientX);
  }
  if ($(event.target).is("#2")) {
    $("#JavaScript").css("left", event.clientX);
    $("#CSS").css("right", codeboxWidth - event.clientX);

  }
  if ($(event.target).is("#3")) {
    $("#Output").css("left", event.clientX);
    $("#JavaScript").css("right", codeboxWidth - event.clientX);
  }
}

$(".resize").draggable({
  axis: "x"
});

function dragging(event) {
  var CSS_left = parseInt($("#CSS").css("left"));
  var JavaScript_left = parseInt($("#JavaScript").css("left"));
  var Output_left = parseInt($("#Output").css("left"));
  var offset = 100;
  var checkOverlap1 = $(event.target).is("#1") 
                      && event.clientX + offset <= JavaScript_left 
                      && event.clientX >= offset;
  var checkOverlap2 = $(event.target).is("#2") 
                      && event.clientX + offset <= Output_left 
                      && event.clientX - offset >= CSS_left;
  var checkOverlap3 = $(event.target).is("#3") 
                      && event.clientX - offset >= JavaScript_left 
                      && event.clientX <= codeboxWidth - offset;

  if (checkOverlap1 || checkOverlap2 || checkOverlap3) {
    resize(event);
  }
}
body {
  margin: 0;
  padding: 0;
  overflow-y: hidden;
  overflow-x: hidden;
  background: #F7F7F7;
  font-family: Arial;
}
#topbar {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 35px;
  background: #EEEEEE;
  position: relative;
}
h2 {
  margin: 2px 0 0 0;
  padding: 0;
  float: left;
  position: absolute;
}
#control {
  width: 100%;
  margin: 8px 0 0 0;
  padding: 0;
  position: absolute;
  text-align: center;
}
.option {
  margin: 0 -5px 0 0;
  padding: 5px 10px 5px 10px;
  text-align: center;
  border-top: 1px solid #CCC;
  border-bottom: 1px solid #CCC;
  border-left: 1px solid #CCC;
  text-decoration: none;
  font-size: 0.9em;
  color: black;
}
.option:first-child {
  border-bottom-left-radius: 5px;
  border-top-left-radius: 5px;
}
.option:last-child {
  border-right: 1px solid #CCC;
  border-bottom-right-radius: 5px;
  border-top-right-radius: 5px;
}
.option:hover {
  background: #dee5e5;
}
.opactive {
  background: #EBF3FF;
}
.opinactive {
  background: 0;
}
.active {
  display: block;
}
.inactive {
  display: none;
}
#codebox {
  margin: 0;
  padding: 0 width: 100%;
  position: static;
  top: 35px;
  background: white;
}
.content {
  margin: 0;
  padding: 0;
  min-width: 10%;
  max-width: 100%;
  position: absolute;
  float: left;
  color: #6DCAFC;
  background: #F7F7F7;
  overflow: hidden;
}
.resize {
  top: 35px;
  bottom: 0px;
  width: 1px;
  margin-left: 0;
  height: 100%;
  right: auto;
  opacity: 0;
  position: absolute;
  cursor: ew-resize;
  border-left-width: 1px;
  border-left-style: solid;
  border-left-color: rgba(218, 218, 218, 0.498039);
  z-index: 99999;
  background: #666;
}
.contentheader {
  margin: 0;
  padding: 0;
  background: transparent;
  position: relative;
}
.selectedcontent {
  background: white;
}
.contentbox {
  width: 100%;
  height: 100%;
  background: transparent;
  position: relative;
  box-sizing: border-box;
  border-right: 1px solid darkgrey;
  overflow: hidden;
}
.editbox {
  width: 100%;
  height: 100%;
  background: transparent;
  overflow: hidden;
}
.textareabox {
  background: transparent;
  min-width: 100%;
  max-width: 100%;
  min-height: 100%;
  max-height: 100%;
  border: none;
  outline: none;
  resize: none;
}
<!DOCTYPE html>
<html>

<head>
  <title>Project 04</title>
  <link rel="stylesheet" type="text/css" href="styles.css">
  <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">

</head>

<body>
  <div id="topbar">
    <h2>Code Runner</h2>
    <div id="control">
      <a href="#" class="option opactive">HTML</a>
      <a href="#" class="option opactive">CSS</a>
      <a href="#" class="option opactive">JavaScript</a>
      <a href="#" class="option opactive">Output</a>
    </div>
  </div>

  <div id="codebox">
    <div id="HTML" class="content active">
      <div class="contentbox">
        <div class="contentheader">HTML</div>
        <div class="editbox" id="HTMLeditbox">
          <textarea id="HTMLcode" class="textareabox"></textarea>
        </div>
      </div>
    </div>

    <div class="resize active" id="1" style="left: 25%" ondrag="dragging(event)"></div>

    <div id="CSS" class="content active">
      <div class="contentbox">
        <div class="contentheader">CSS</div>
        <div class="editbox" id="CSSeditbox">
          <textarea id="CSScode" class="textareabox"></textarea>
        </div>
      </div>
    </div>

    <div class="resize active" id="2" style="left: 50%" ondrag="dragging(event)"></div>

    <div id="JavaScript" class="content active">
      <div class="contentbox">
        <div class="contentheader">JavaScript</div>
        <div class="editbox" id="JavaScripteditbox">
          <textarea id="JavaScriptcode" class="textareabox"></textarea>
        </div>
      </div>
    </div>

    <div class="resize active" id="3" style="left: 75%" ondrag="dragging(event)"></div>

    <div id="Output" class="content active">
      <div class="contentbox">
        <div class="contentheader">Output</div>
        <div class="editbox" id="Outputbox">

        </div>
      </div>
    </div>
  </div>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>


  <script type="text/javascript" src="jscript.js"></script>
</body>

</html>

Here's a JSBin based on your example.

这是一个基于您的示例的JSBin。