Jquery列可拖动树div

Posted

技术标签:

【中文标题】Jquery列可拖动树div【英文标题】:Jquery columns draggable tree div 【发布时间】:2017-03-20 01:03:31 【问题描述】:

我有一个问题,我想这样做可以移动 3 div(稍后更多)以在 X 轴上移动 min 和 max 具有相对于容器的位置。 最初效果很好但是当你开始移动分隔符几次时开始出现问题,不尊重最小值或最大值,我想知道是否有人可以帮助我知道可能是什么问题(他们可以在浏览器控制台中检查值​​根据移动分隔符更新。)https://jsfiddle.net/66un403y/

$( document ).ready(function() 

$(function()
   var A = parseInt($('#A').width()),
       B = parseInt($('#B').width()),
       C = parseInt($('#C').width()),

       minw       = parseInt((A + B + C) * 10 / 100), //  min 10 percentage
       offset     = $('#container').offset(),
       containw   = $('#container').outerWidth(),
       splitter_1 = $('#container').outerWidth() / 3;
       splitter_2 = (($('#container').outerWidth() / 3) * 2);

       $("#min_width").text(minw + "px");

       splitter = function(event, ui)
            $( '#DragContent' ).unbind( 'draggable' );
            A = parseInt(ui.position.left);
            B = Math.abs(containw - A - C);
            C = containw - A - B;

            splitter_1 = ui.position.left;
            splitter_2 = splitter_2;
            console.log("A:" + A);
            console.log("B:" + B);
            console.log("C:" + C);
            console.log("splitter_1:" + splitter_1);
            console.log("splitter_2:" + splitter_2);
            console.log("offset.left:"+offset.left);
            console.log("ui.position.left:"+ ui.position.left);
            console.log("max:"+ (A + B - minw));
            console.log("min:"+ ( minw ));

            // update the new limits
            //$( '#X' ).unbind( 'draggable' );
            $( '#X' ).draggable(
              containment : [
                 offset.left + minw,
                 offset.top,
                 offset.left + C + B - minw,
                 offset.top + $('#container').height()
            ]);


           //set widths and information...
           $('#A').css(width : A).children().text("current px: " + A);
           $('#B').css(width : B).children().text("current px: " + B);
           $('#C').css(width : C).children().text("current px: " + C);;
       ;
       splitter2 = function(event, ui)


          C = containw - (ui.position.left);
            B = Math.abs( ui.position.left - A );//parseInt(ui.position.left) - A - C;
          A = containw - (B + C);

         splitter_1 = splitter_1;
         splitter_2 = ui.position.left;
         console.log("A:" + A);
         console.log("B:" + B);
         console.log("C:" + C);
         console.log("splitter_1:" + splitter_1);
         console.log("splitter_2:" + splitter_2);
         console.log("offset.left:"+offset.left);
         console.log("ui.position.left:"+ ui.position.left);
         console.log("limite:"+ (containw - minw));
         console.log("minimo:"+ ( A + minw ));



         // update the new limits
         //$( '#X' ).unbind( 'draggable' );
         $('#Z').draggable(
          containment : [
             offset.left + A + minw,
             offset.top,
             offset.left + containw - minw,
             offset.top + $('#container').height()
        ]);
         $('#A').css(width : A).children().text("current px: " + A);
         $('#B').css(width : B).children().text("current px: " + B );
         $('#C').css(width : C).children().text("current px: " + C  );

       ;

   $('#X').draggable(
      axis : 'x', 
      drag : splitter,
      containment : [
                   offset.left + minw,
                   offset.top,
                   offset.left + C + B - minw,
                   offset.top + $('#container').height()
              ]
   );

   $('#Z').draggable(
       axis : 'x',
       drag : splitter2,
       containment : [
             offset.left + A + minw,
             offset.top,
             offset.left + containw - minw,
             offset.top + $('#container').height()
        ]
   );


   //information...
   $('#width').text(A + B + C);
   $('#A div').text("current px: " + A );
   $('#B div').text("current px: " + B );
   $('#C div').text("current px: " + C );
   console.log();
);

);

【问题讨论】:

即使在调整窗口大小时,您的代码也不好。分隔符不合适... :( 是的,如果您将窗口放大,请再次按运行。但我希望有人帮助我解决我遇到的问题 修复了在拖动结束时将所有内容转换回 % 的问题 【参考方案1】:

很抱歉没有处理您的确切代码,只是为了向您展示我将如何创建

可调整大小的同级容器

jsBin demo

将处理任意数量的 resizable 框,并保持它们响应thanx 宽度转换回% 调整大小结束:

var minWidth = 50, // Set here the minimal resize width
    $box = $(".box"),
    $cont = $box.parent(),

    startX = 0,
    isDrag = false,

    $that, thatW = 0,
    $next, nextW = 0;

$(".resizeHandler").on('mousedown', function( e ) 

  isDrag = true;
  startX = e.pageX;

  $that = $(this).closest(".box");
  thatW = $that.width();

  $next = $that.next(".box");
  nextW = $next.width();
  
  $box.css(userSelect: isDrag?'none':'auto');

);

$(document).on('mousemove', function( e ) 

  if(!isDrag) return;
  var x = e.pageX;

  var nextWNew = Math.max(minWidth, nextW + startX - x);
  var thatWNew = Math.max(minWidth, thatW + x - startX);
  if(thatWNew <= 50) return thatWNew = minWidth;
  if(nextWNew <= 50) return nextWNew = minWidth;
  $that.width(thatWNew);
  $next.width(nextWNew);

).on("mouseup", function() 

  isDrag = false;
  // Convert widths to percent (to keep responsiveness)
  var contW = $cont.width();
  $box.css("width", function(i, w)
    return (parseInt(w,10) / contW * 100) +"%";
  );

);
*margin:0;box-sizing:border-box;html,bodyheight:100%;font:14px/1.4 sans-serif;

.box 
  width: 33.333%;
  float: left;
  background: #eee;
  position: relative;

.box:last-child .resizeHandler 
  display:none;

.boxContent
  padding: 16px;
  height: 200px;
  overflow: hidden;
  overflow-y: auto;

.resizeHandler 
  position: absolute;
  z-index:2;
  top: 0;
  height: 100%;
  width: 6px;
  right: -6px;
  background: blue;
  cursor: e-resize;
 .resizeHandler:hover 
  background: green;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="boxes">
  
  <div class="box">
    <div class="boxContent">
      Adipisicing elit. Distinctio numquam accusantium perspiciatis quis ipsam modi optio odio quaerat magni! Repellendus, maxime voluptatum et sunt nobis, quae consequatur minus? Ducimus, voluptate!
    </div>
    <div class="resizeHandler"></div>
  </div>
  
  <div class="box">
    <div class="boxContent">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit.
    </div>
    <div class="resizeHandler"></div>
  </div>
  
  <div class="box">
    <div class="boxContent">
      Sit amet, consectetur adipisicing elit. Asperiores porro, ut aliquam, laudantium esse pariatur nihil provident vero quam excepturi. Incidunt fugit sit nihil, exercitationem sequi obcaecati, error impedit aspernatur!
    </div>
    <div class="resizeHandler"></div>
  </div>
  
</div>

如您所见,我将处理程序移入每个盒子。 在处理程序拖动/移动时,我定位/修改处理程序的父框的宽度和下一个兄弟框的宽度。差不多就是这样。代码应该是不言自明的,但与往常一样,如果您有任何问题,请随时提出。


动态添加.box.row

这是一个动态创建 BOX 和 ROW 的示例:jsBin demo

var minWidth = 50, // Set here the minimal resize width
    $box = $(".box"),
    $cont = $box.parent(),

    startX = 0,
    isDrag = false,

    $that, thatW = 0,
    $next, nextW = 0;




// GRIDDER ////////////////
var $selectedBox = null,
    $selectedRow = null,
    b = 0;

function newBox() 
  return $("<div/>", 
    class: "box",
    css: width:"100%",
    html : "<div class='boxContent' contenteditable>BOX "+ (b++) +"</div>"+
    "<div class='resizeHandler'></div>"
  );


$(document).on("click", ".box", function()

  $selectedBox = $(this);
  $selectedRow = $selectedBox.closest(".row");

).on("click", "#addRow", function() 

  if(!$selectedBox) return alert("Select a box first");
  $("<div/>", 
    class: "row",
    append: newBox(),
    insertAfter: $selectedRow
  );

).on("click", "#addBox", function() 

  if(!$selectedBox) return alert("Select a box first");
  var $newBox = newBox();
  $selectedBox.after($newBox);

  var $rowBoxes = $selectedRow.find(".box"),
      totBoxes = $rowBoxes.length;

  $rowBoxes.css("width", function(i, w)
    return (100/totBoxes) +"%";
  );

);



// RESIZER ////////////////

$(document).on('mousemove', ".row", function( e ) 

  if(!isDrag) return;
  var x = e.pageX;

  var nextWNew = Math.max(minWidth, nextW + startX - x);
  var thatWNew = Math.max(minWidth, thatW + x - startX);
  if(thatWNew <= 50) return thatWNew = minWidth;
  if(nextWNew <= 50) return nextWNew = minWidth;
  $that.width(thatWNew);
  $next.width(nextWNew);

).on('mousedown', ".resizeHandler", function( e ) 

  isDrag = true;
  startX = e.pageX;

  $that = $(this).closest(".box");
  thatW = $that.width();

  $next = $that.next(".box");
  nextW = $next.width();

  $box.css(userSelect: isDrag?'none':'auto');

).on("mouseup", function() 

  isDrag = false;
  // Convert widths to percent (to keep responsiveness)
  var contW = $cont.width();
  $box.css("width", function(i, w)
    return (parseInt(w,10) / contW * 100) +"%";
  );

)
*margin:0;box-sizing:border-box;html,bodyheight:100%;font:14px/1.4 sans-serif;

.row
  clear:both;
  margin:10px 0;
  overflow:auto;

.box 
  width: 25%;
  float: left;
  background: #eee;
  position: relative;

.box:last-child .resizeHandler 
  display:none;

.boxContent
  padding: 16px;
  height: 200px;
  overflow: hidden;
  overflow-y: auto;

.resizeHandler 
  position: absolute;
  z-index:2;
  top: 0;
  height: 100%;
  width: 6px;
  right: -6px;
  background: #448;
  cursor: e-resize;
 .resizeHandler:hover 
  background: #000;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="addRow">ADD ROW AFTER</button>
    <button id="addBox">ADD BOX AFTER</button>

    <div id="page">
      <div class="row">
        <div class="box">
          <div class="boxContent" contenteditable>
            Adipisicing elit. Distinctio numquam accusantium perspiciatis quis ipsam modi optio odio quaerat magni! Repellendus, maxime voluptatum et sunt nobis, quae consequatur minus? Ducimus, voluptate!
          </div>
          <div class="resizeHandler"></div>
        </div>
        <div class="box">
          <div class="boxContent" contenteditable>
            Sit amet, consectetur adipisicing elit. Asperiores porro, ut aliquam, laudantium esse pariatur nihil provident vero quam excepturi. Incidunt fugit sit nihil, exercitationem sequi obcaecati, error impedit aspernatur!
          </div>
          <div class="resizeHandler"></div>
        </div>
        <div class="box">
          <div class="boxContent" contenteditable>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit.
          </div>
          <div class="resizeHandler"></div>
        </div>
        <div class="box">
          <div class="boxContent" contenteditable>
            Ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus non officia illum odit, optio inventore ad vero eos sed voluptas recusandae vel quod natus magnam totam quos, repellat mollitia veniam!
          </div>
          <div class="resizeHandler"></div>
        </div>
      </div>
    </div>

【讨论】:

如何使这个动态化?,我努力在 3 列中做到这一点,但想要动态的东西是一个函数希望框 add_row_column(3 or 2 or 1 or 4) 适合列数.例子。 i.imgur.com/X4eUN60.jpg 我可以通过 jquery.append 添加每一行,但我希望你帮助我使用该 div 容器中的一个函数来满足每行需要的列数,请 @iLen 是的,为了在每个 .boxes 中动态附加 .box,您应该稍微调整一下上面的代码。我会告诉你如何 如果您动态添加第 1 列函数,请您帮我大忙,希望您的代码,谢谢 @iLen 是这样的吗? jsbin.com/lurawu/11/edit?html,css,js,console,output 保持健康,你很好。我想在图片中像这样工作,我认为它是您的代码,非常快速和简单,您可以帮我看看它看起来像图像吗? i.imgur.com/80ImJG2.png pd:我帮了很多忙,我在一些邮件中不遗余力?

以上是关于Jquery列可拖动树div的主要内容,如果未能解决你的问题,请参考以下文章

Qt C++ 在表之间拖动 QHeaderView

easyui:怎么让某一列可编辑?

遍历并显示隐藏的子div jquery

查找子图像宽度并将其应用于包含父 div jquery

在鼠标移动时设置Jquery Draggable文本的顶部和左侧?

jquery如何通过拖动边框改变该div的大小