拖放后再次放置元素

Posted

技术标签:

【中文标题】拖放后再次放置元素【英文标题】:Drop the element again after Drag and Drop 【发布时间】:2018-08-21 13:13:52 【问题描述】:

我正在尝试使用 jQuery UI 拖放 功能来构建 UI,但被困在一个实例中。基本上,我正在做的是使内容框在区域中可拖放。

我正在克隆一个可拖动的框并放入该区域。这样做的问题是,当一个元素被拖放到任何区域时,它应该被拖动并且可以再次被拖放到任何相应的区域

我一直在寻找它的解决方案,但没有找到任何帮助。

谢谢

以下是我正在处理的代码。

/**/
	
	var blockBoxEle = $('.block-box');
	var blockBoxWd = blockBoxEle.width();
	blockBoxEle.css('width': blockBoxWd);
	var blockBoxLen = blockBoxEle.length;
	for(var x=0; x<blockBoxLen; x++) 
			blockBoxEle.eq(x).addClass('block-count'+(x+1));
	
	
	blockBoxEle.draggable(
	  revert: "invalid",
	  stack: blockBoxEle,
	  helper: 'clone',
	  stop: function(e, ui) 
		  
	  
	);
	console.log('blockBoxElements Loaded!!!!!!!');
	
	
	/**/
	var areaBoxEle = $('.area-box');
	var areaBoxLen = areaBoxEle.length;
    for(var y=0; y<areaBoxLen; y++) 
        areaBoxEle.eq(y).prop('id', 'areaBox'+(y+1));
    
	areaBoxEle.droppable(
	  accept: blockBoxEle,
	  tolerance: "pointer",
	  //greedy: true,
	  drop: function(event, ui) 
		var droppable = $(this);
		var draggable = ui.draggable;
		 if (droppable.find('.ui-draggable').length) return; 
		var dragClass = draggable.attr("class").split(' ')[1];
		
		var drag = areaBoxEle.has(ui.draggable).length ? draggable : draggable.clone().draggable(
		  revert: "invalid",
		  stack: blockBoxEle,
		  helper: 'clone'
		);
		
		droppable.empty();
		droppable.after(drag).hide();
		console.log('Dropped block class:'+dragClass+' on area id:'+this.id);
	  
	);
	console.log('areaBoxElements Loaded!!!!!!!');
.block-box,
.area-box  margin: 0 0 10px; text-align: center; position: relative; 
.block-box  padding: 10px 5px; border: 2px solid #000; background: red; color: #fff; max-width: 100%; min-width: 100%; z-index: 2; 
.area-box  padding: 30px 5px; border: 2px dashed #333; background: #eee; z-index: 1; 
.block-box h3,
.area-box h3  margin: 0; font-size: 14px; font-weight: 700; 
#block-fields .block-box  padding-top: 30px; padding-bottom: 30px; 
<link href="https://code.jquery.com/ui/1.12.1/jquery-ui.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<div class="panel panel-default">
	<div class="panel-body">
		<div class="row">
			<div id="block-panel" class="col-xs-3">
				<div class="row">
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 1</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 2</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 3</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 4</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 5</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 6</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 7</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 8</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 9</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 10</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 11</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 12</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 13</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 14</h3>
						</div>
					</div>
					<div class="col-xs-6">
						<div class="block-box">
							<h3>Field 15</h3>
						</div>
					</div>
				</div>
			</div>
			<div id="block-fields" class="col-xs-9">
				<div class="row">
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 1</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 2</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 3</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 4</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 5</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 6</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 7</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 8</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 9</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 10</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 11</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 12</h3>
						</div>
					</div>
					<div class="col-xs-3">
						<div class="area-box">
							<h3>Area 13</h3>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

【问题讨论】:

我发现.draggable()最好在元素添加后初始化。将克隆添加到放置区域后尝试重新初始化可拖动。 嗨@Twisty,实际上当盒子被拖到区域时,在它被拖动后,它不是它的克隆,而是同一个盒子..克隆只会在第一次创建之后该框只能移动。 所以我认为正在发生的事情是你有一个不再属于blockBoxEle 的新元素,因此,droppable 不会接受它:accept: blockBoxEle。第一次就被接受了,很奇怪。所以也许不是这样,但这是我唯一能想到的。 【参考方案1】:

微小的变化解决了这个问题。设置 accept: ".block-box" 允许 drop 接受任何可拖动对象。

$(function() 
  function makeFirstDrag($el, $s) 
    $el.draggable(
      revert: "invalid",
      stack: $s,
      helper: 'clone'
    );
  

  function makeSecondDrag($el, $s) 
    $el.draggable(
      revert: "invalid",
      stack: $s,
      helper: 'clone',
      start: function(e, ui) 
        $(this).css("opacity", ".25");
      ,
      stop: function(e, ui) 
        $(this).prev().show();
        $(this).remove();
      
    );
  
  var blockBoxEle = $('.block-box');
  var blockBoxWd = blockBoxEle.width();
  blockBoxEle.css(
    'width': blockBoxWd
  );
  var blockBoxLen = blockBoxEle.length;
  for (var x = 0; x < blockBoxLen; x++) 
    blockBoxEle.eq(x).addClass('block-count' + (x + 1));
  

  makeFirstDrag(blockBoxEle, blockBoxEle);
  console.log('blockBoxElements Loaded!!!!!!!');

  var areaBoxEle = $('.area-box');
  var areaBoxLen = areaBoxEle.length;
  for (var y = 0; y < areaBoxLen; y++) 
    areaBoxEle.eq(y).prop('id', 'areaBox' + (y + 1));
  
  areaBoxEle.droppable(
    accept: ".block-box",
    tolerance: "pointer",
    drop: function(event, ui) 
      var droppable = $(this);
      var draggable = ui.draggable;
      if (droppable.find('.ui-draggable').length) return;
      var dragClass = draggable.attr("class").split(' ')[1];


      var drag = areaBoxEle.has(ui.draggable).length ? draggable : draggable.clone().draggable(
        revert: "invalid",
        stack: blockBoxEle,
        helper: 'clone'
      );
      drag.css("opacity", "1");
      makeSecondDrag(drag, blockBoxEle);

      //droppable.empty();
      droppable.addClass("hiding").hide().after(drag);
      console.log('Dropped block class:' + dragClass + ' on area id:' + this.id);
    
  );
  console.log('areaBoxElements Loaded!!!!!!!');
);
.block-box,
.area-box 
  margin: 0 0 10px;
  text-align: center;
  position: relative;


.block-box 
  padding: 10px 5px;
  border: 2px solid #000;
  background: red;
  color: #fff;
  max-width: 100%;
  min-width: 100%;
  z-index: 2;


.area-box 
  padding: 30px 5px;
  border: 2px dashed #333;
  background: #eee;
  z-index: 1;


.block-box h3,
.area-box h3 
  margin: 0;
  font-size: 14px;
  font-weight: 700;


#block-fields .block-box 
  padding-top: 30px;
  padding-bottom: 30px;
<link href="https://code.jquery.com/ui/1.12.1/jquery-ui.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<div class="panel panel-default">
  <div class="panel-body">
    <div class="row">
      <div id="block-panel" class="col-xs-3">
        <div class="row">
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 1</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 2</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 3</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 4</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 5</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 6</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 7</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 8</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 9</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 10</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 11</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 12</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 13</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 14</h3>
            </div>
          </div>
          <div class="col-xs-6">
            <div class="block-box">
              <h3>Field 15</h3>
            </div>
          </div>
        </div>
      </div>
      <div id="block-fields" class="col-xs-9">
        <div class="row">
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 1</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 2</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 3</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 4</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 5</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 6</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 7</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 8</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 9</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 10</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 11</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 12</h3>
            </div>
          </div>
          <div class="col-xs-3">
            <div class="area-box">
              <h3>Area 13</h3>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

更新

为可拖动添加了许多 startstop 回调,以帮助模拟您想要的活动。我还将它们移到了它们自己的函数中,以使其更易于操作。

【讨论】:

嗨@Twisty,感谢您的回答。我认为我的问题的一部分已经解决了关于再次丢弃的问题,但我不希望再次拖动克隆,而是已经在区域中的原始框。 在选择一滴之前你想要一个幽灵吗?还是您希望它显示该字段已被拾取并正在被拖动? 第二个,当一个克隆框被拖入区域时,它可以被拖到任何区域而不进行克隆。 @SaurabhLP 您将不想在第二次初始化中使用clone 选项。 很好的更新,非常感谢。这就是我想要的。

以上是关于拖放后再次放置元素的主要内容,如果未能解决你的问题,请参考以下文章

拖放后将元素的位置保存到本地文件

使用jquery ui拖放后的动态div宽度

拖放后向可拖放项目添加标签

拖放后无法访问元素

css / html5:拖放后悬停状态保持不变

拖放后的jQuery UI Sortable停止事件