使用.remove()时防止jQuery可拖动元素离开父DIV?

时间:2017-11-07 22:18:04

标签: javascript jquery css jquery-ui

我有一个jQuery fiddle使用jQuery UI draggable来演示这个问题。这是HTML:

<div id="container">
  <div id="components">
    <p>
      Components: Click to add a component.
    </p>
    <div class="component">
      <div class="component-title">
        One
      </div>
    </div>
    <div class="component">
     <div class="component-title">
       Two
     </div>
    </div>
    <div class="component">
      <div class="component-title">
        Three
      </div>
    </div>
  </div>
  <div id="workspace">
    <div id="pdc">

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

这是CSS:

#workspace {
  padding-top: 20px;
  clear: both;
}

#pdc {
  border: 1px solid #000000;
  border-radius: 5px;
  width: 300px;
  height: 150px;
  position: relative;
}

.component-title {
  cursor: default;
}

#pdc .component-title {
  cursor: move;
}

.component {
  border: 1px solid #000000;
  border-radius: 5px;
  text-align: center;
  width: 98px;
  height: 48px;
}

#components .component {
  float: left;
  margin: 0 12px 0 0;
}

#pdc .component {
  cursor: move;
  display: inline-block;
}

.component-delete {
  float: right;
  color: pink;
  margin-right: 5px;
  cursor: pointer;
}

.component-delete:hover {
  color: red;
}

这是jQuery:

$(document).ready(function() {
    $('.component').click(function(){
    var lastpdccomponent, html = $(this).clone().prepend('<div class="component-delete">X</div>');
        if ($('#pdc').children().length > 0) {
            lastpdccomponent = $('#pdc').children().last();
            $('#pdc').append(html);
            $('#pdc').children().last().position({
                my: "left top", 
                at: "left bottom", 
                of: lastpdccomponent
            });
        } else {
            $('#pdc').append(html);
        }
        $('#pdc .component').draggable({
            containment: '#pdc', 
            scroll: false, 
            grid: [50, 50]
        });
  });
  $('#pdc').on('click', '.component-delete', function() {
    $(this).parent().remove();
  });
});

它的设置使得如果单击一个组件(一,二或三),组件将被克隆并添加到“pdc”div中,如下图所示:

Image of three added components.

如果拖动第二个和第三个组件,使它们与第一个组件在水平行中:

Three components aligned horzontally

然后通过单击红色“X”删除第一个组件,其他组件移动到容器外部,如下图所示:

Components two and three move out of the container when component one is deleted.

我已尝试过组件的其他显示选项,例如“inline-block”,它解决了删除组件水平行中第一个的问题,但在垂直行中的第一个引入了新问题组件被删除;在这种情况下,剩余的元素移动到容器的左侧。

如果删除行中的第一个组件,如何防止其他组件移出容器?

3 个答案:

答案 0 :(得分:1)

.component设置为position: absolute;,这应该会解决,因为您的容器#pdc已设置为position: relative;。当你删除其他人定位的元素时,一切都变得疯狂,但当它们绝对定位时,它们应该保持不变。

同时将#components .component设置为position: static;,因为您不需要定位。

请参阅this fiddle了解演示

CSS更改:

.component {
  position: absolute;  /*Add this*/
  border: 1px solid #000000;
  border-radius: 5px;
  text-align: center;
  width: 98px;
  height: 48px;
}

#components .component {
  position: static; /*Add this*/
  float: left;
  margin: 0 12px 0 0;
}

答案 1 :(得分:1)

position的{​​{1}}是.component,因此正在根据前面的元素计算。删除第一个后续位置时,后续位置将不再正确计算。为了防止出现这种情况,只需在{c}中将relative添加到position:absolute;以使组件的位置计算彼此独立,请参阅代码段:

更新我看到当有滚动条时,元素的位置变得混乱,所以为了解决这个问题,请将#pdc .component{添加到

collision: 'none'

请参阅更新的代码段:

&#13;
&#13;
$('#pdc').children().last().position({
            my: "left top", 
            at: "left bottom", 
            of: lastpdccomponent,
            collision: 'none'
        });
&#13;
$(document).ready(function() {
	$('.component').click(function(){
  	var lastpdccomponent, html = $(this).clone().prepend('<div class="component-delete">X</div>');
		if ($('#pdc').children().length > 0) {
			lastpdccomponent = $('#pdc').children().last();
			$('#pdc').append(html);
			$('#pdc').children().last().position({
				my: "left top", 
				at: "left bottom", 
				of: lastpdccomponent,
                collision: 'none'
			});
		} else {
			$('#pdc').append(html);
		}
		$('#pdc .component').draggable({
			containment: '#pdc', 
			scroll: false, 
			grid: [50, 50]
		});
  });
  $('#pdc').on('click', '.component-delete', function() {
  	$(this).parent().remove();
  });
});
&#13;
#workspace {
  padding-top: 20px;
  clear: both;
}

#pdc {
  border: 1px solid #000000;
  border-radius: 5px;
  width: 300px;
  height: 150px;
  position: relative;
}

.component-title {
  cursor: default;
}

#pdc .component-title {
  cursor: move;
}

.component {
  border: 1px solid #000000;
  border-radius: 5px;
  text-align: center;
  width: 98px;
  height: 48px;
}

#components .component {
  float: left;
  margin: 0 12px 0 0;
}

#pdc .component {
  cursor: move;
  position:absolute;
}

.component-delete {
  float: right;
  color: pink;
  margin-right: 5px;
  cursor: pointer;
}

.component-delete:hover {
  color: red;
}
&#13;
&#13;
&#13;

答案 2 :(得分:0)

问题在于点击.component-delete时,组件不会“重置”到其默认位置,并且内联height-50px(和{{} 1}} offset)。

您可以通过手动重置其位置来解决此问题,并添加:

left

删除功能,导致以下内容:

$(this).parent().siblings().css('top', '0');
$(this).parent().siblings().css('left', '0');

这将使第二个和第三个元素向左移动两个并在删除第一个元素时垂直堆叠,如工作 here 所示。

不幸的是,我不认为删除时可以将剩余的两个元素保留在水平线上,就像省略重置$('#pdc').on('click', '.component-delete', function() { $(this).parent().siblings().css('top', '0'); $(this).parent().siblings().css('left', '0'); $(this).parent().remove(); }); 位置一样,第二个元素将采用height偏移量从第一个。希望这仍然足够。

希望这有帮助! :)