如何将可拖动的元素放入可排序的元素中,放置的项目不是原始元素而是自定义助手
Posted
技术标签:
【中文标题】如何将可拖动的元素放入可排序的元素中,放置的项目不是原始元素而是自定义助手【英文标题】:How to drop a draggable into a sortable, the droppped item is not the original element but a custom helper 【发布时间】:2016-06-27 03:42:18 【问题描述】:jQuery draggeble/sortable demo 仅显示如何放置可拖动的克隆(可拖动和可排序项目具有相同的结构)。我想删除不同的 DOM 结构。例如,当我拖动一个简单的 div 时,拖动的元素会转换为更复杂的 DOM 结构。请参阅jsfidler 示例,注意帮助程序如何更改,我想删除帮助程序但原来的项目被删除了。
使用简单的可拖动项目和可放置容器有效,但我希望能够将项目放置在可排序容器的任何部分并能够重新排序元素。
知道如何实现我想要的吗?
$(function()
$(".portlet-container").sortable(
handle: ".portlet-header",
cursor: "move",
placeholder: "ui-state-highlight"
).droppable(
accept: ".portlet-clone",
drop: function(event, ui)
return $(ui.helper).clone(true, true)
.removeClass('ui-draggable-dragging')
.removeClass('portlet-clone')
.css("position", "")
.css("left", "")
.css("top", "").appendTo(this);
);
$('.portlet-name').draggable(
connectToSortable: ".portlet-container",
cursor: 'move',
revert: 'invalid',
opacity: 0.7,
helper: portletHelper
);
function portletHelper(event)
var portletWrapperStr = "<div class='portlet-wrapper portlet-clone' style='height:" + $(this).data("div-height") + "px; width:" + $(this).data("div-width") + "px;'/>";
var portletStr = "<div class='portlet' " +
"style='height:" + ($(this).data("div-height") - 40 - 2) + "px;'>" +
"<div class='portlet-header'>" + $(this).html() + "</div>" +
"</div>";
var portlet = $(portletStr);
var portletWrapper = $(portletWrapperStr).append(portlet);
return portletWrapper;
);
.portlet-container
display: inline-block;
margin-top: 10px;
margin-bottom: 10px;
width: 960px;
.portlet-wrapper
overflow: hidden;
.portlet
border-radius: 4px;
border: 1px solid #bbb;
background-color: white;
padding: 10px 10px;
margin-top: 10px;
margin-bottom: 10px;
position: relative;
overflow: hidden;
.portlet-header
height: 25px;
.portlet-content
margin-bottom: 10px;
.portlet-options
float: right;
.portlet-placeholder
border: 1px dotted black;
margin: 0 1em 1em 0;
height: 95%;
.portlets-items
width: 220px;
.portlet-item
margin: 2px;
display: inline-block;
width: 220px;
height: 25px;
.portlet-name
width: 140px;
font-family: Akkurat, Helvetica, Arial, sans-serif;
font-size: 12px;
color: #5c5e5f;
border-radius: 2px;
border: 1px solid #bbb;
padding: 2px;
display: inline-block;
<title>Drag and Drop</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="dragndrop.js"></script>
<body>
<div class="portlet-items">
<div class="portlet-item">
<div class="portlet-name" data-div- data-div->
dragabble narrow 1
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div->
dragabble narrow 2
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div->
dragabble wide 1
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div->
dragabble wide 2
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div->
dragabble wide 3
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div->
dragabble wide 4
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div->
dragabble wide 5
</div>
</div>
</div>
<div class="portlet-container">
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet" style="height:188px;">
<div class="portlet-header">Portlet 6</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet" style="height:188px;">
<div class="portlet-header">Portlet 5</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet" style="height:188px;">
<div class="portlet-header">Portlet 1</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet" style="height:188px;">
<div class="portlet-header">Portlet 3</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet" style="height:188px;">
<div class="portlet-header">Portlet 2</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet" style="height:188px;">
<div class="portlet-header">Portlet 9</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet" style="height:188px;">
<div class="portlet-header">Portlet 8</div>
<div class="portlet-content">content</div>
</div>
</div>
</div>
</body>
【问题讨论】:
【参考方案1】:好的,以下解决了您的问题:
JSFiddle
当我们将元素拖放到可排序对象上时,我们必须更新拖放的元素 html 并将其设置为您想要的。
当您已经将可拖动对象链接到可排序列表时,您不必添加可放置对象。
$( function()
$( ".portlet-container" ).sortable(
cursor : "move",
placeholder: "ui-state-highlight",
handle: ".portlet-header",
update: function(event, ui)
if($(ui.item).hasClass('portlet-wrapper'))
// we don't add one if we're sorting a pre-existing item
else
ui.item.html(portletClone(ui.item))
ui.item.removeClass('portlet-item portlet-name ui-draggable')
.addClass('portlet-wrapper');
);
$('.portlet-name').draggable(
connectToSortable: ".portlet-container",
cursor: 'move',
revert: 'invalid',
opacity: 0.7,
helper: portletHelper
);
function portletHelper( event )
return portletClone(this);
function portletClone(item)
var portletWrapperStr = "<div class='portlet-wrapper portlet-clone' style='height:"+$(item).data("div-height")+"px; width:"+$(item).data "div-width")+"px;'/>";
var portletStr ="<div class='portlet' "+
" style='height:"+($(item).data("div-height")-40-2) +"px;'>"+
" <div class='portlet-header'>"+$(item).html()+"</div>"+
"</div>";
var portlet = $(portletStr);
var portletWrapper = $(portletWrapperStr).append(portlet);
return portletWrapper;
);
.portlet-container
display: inline-block;
margin-top:10px;
margin-bottom:10px;
width: 960px;
.portlet-wrapper
overflow:hidden;
.portlet
border-radius: 4px;
border: 1px solid #bbb;
background-color: white;
padding: 10px 10px;
margin-top: 10px;
margin-bottom: 10px;
position:relative;
overflow:hidden;
.portlet-header
height: 25px;
.portlet-content
margin-bottom: 10px;
.portlet-options
float: right;
.portlet-placeholder
border: 1px dotted black;
margin: 0 1em 1em 0;
height: 95%;
.portlets-items
width: 220px;
.portlet-item
margin: 2px;
display: inline-block;
width: 220px;
height: 25px;
.portlet-name
width: 140px;
font-family: Akkurat, Helvetica, Arial, sans-serif;
font-size: 12px;
color: #5c5e5f;
border-radius: 2px;
border: 1px solid #bbb;
padding: 2px;
display: inline-block;
.portlet-action
width: 50px;
margin-left:5px;
color: #5c5e5f;
padding: 2px;
display: inline-block;
<title>Drag and Drop</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>
<script src="dragndrop.js"></script>
<body>
<div class="portlet-items">
<div class="portlet-item">
<div class="portlet-name" data-div- data-div- >
dragabble narrow 1
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div- >
dragabble narrow 2
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div->
dragabble wide 1
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div- >
dragabble wide 2
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div- >
dragabble wide 3
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div- >
dragabble wide 4
</div>
</div>
<div class="portlet-item">
<div class="portlet-name" data-div- data-div- >
dragabble wide 5
</div>
</div>
</div>
<div class="portlet-container">
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet" style="height:188px;">
<div class="portlet-header">Portlet 6</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet" style="height:188px;">
<div class="portlet-header">Portlet 5</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet"
style="height:188px;">
<div class="portlet-header">Portlet 1</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet"
style="height:188px;">
<div class="portlet-header">Portlet 3</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet"
style="height:188px;">
<div class="portlet-header">Portlet 2</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet"
style="height:188px;">
<div class="portlet-header">Portlet 9</div>
<div class="portlet-content">content</div>
</div>
</div>
<div class="portlet-wrapper" style="height:230px;">
<div class="portlet" style="height:188px;">
<div class="portlet-header">Portlet 8</div>
<div class="portlet-content">content</div>
</div>
</div>
</div>
</body>
【讨论】:
谢谢克里斯蒂安,你让我开心,这正是我想要的。我必须添加用 ui.item.replaceWith(portletClone(ui.item)) 替换 ui.item.html(portletClone(ui.item)) 否则主拖动的 div 仍然会导致额外的嵌套 div。谢谢老哥!以上是关于如何将可拖动的元素放入可排序的元素中,放置的项目不是原始元素而是自定义助手的主要内容,如果未能解决你的问题,请参考以下文章