HTML5是否有默认的方法可以将多个元素拖放到同一页面上的另一个html元素中?
似乎HTML5属性draggable
只适用于一个元素,它说:“你可以拖动我,但你需要多个输入设备来选择同时拖动的其他可拖动元素。”
作为解决方法,可以使用js为所选元素添加标识符,并在特定事件中获取所有选定的元素并执行所需操作。但这真的是“正确”的方式吗?
当检查drop
事件时,在处理文件拖放时,会出现多个文件的接口。至少在Chrome中还有items
属性。
不同浏览器之间存在差异。
在Chrome中
drop
事件包含items
属性。
dataTransfer: DataTransfer
items: DataTransferItemList
length: 0
Items
似乎始终为0,无论您是否拖动了项目。
在Firefox中
drop
事件包含 mozItemCount
属性。
dataTransfer: DataTransfer
mozItemCount: 1
mozItemCount
似乎至少为1。
这里有一个小演示
你可以在开发者工具控制台中观察:
此源代码取自此处:http://www.html5rocks.com/en/tutorials/dnd/basics/
$(function(){
// Copied from: http://www.html5rocks.com/en/tutorials/dnd/basics/
var cols_ = document.querySelectorAll('.column');
var dragSrcEl_ = null;
handleDragStart = function(e) {
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
dragSrcEl_ = this;
this.style.opacity = '0.4';
// this/e.target is the source node.
$(this).addClass('moving');
};
handleDragOver = function(e) {
if (e.preventDefault) {
e.preventDefault(); // Allows us to drop.
}
e.dataTransfer.dropEffect = 'move';
return false;
};
handleDragEnter = function(e) {
$(this).addClass('over');
};
handleDragLeave = function(e) {
// this/e.target is previous target element.
$(this).removeClass('over');
};
handleDrop = function(e) {
// this/e.target is current target element.
console.log(e.dataTransfer);
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
// Don't do anything if we're dropping on the same column we're dragging.
if (dragSrcEl_ != this) {
dragSrcEl_.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
}
return false;
};
handleDragEnd = function(e) {
// this/e.target is the source node.
this.style.opacity = '1';
[].forEach.call(cols_, function (col) {
$(col).removeClass('over');
$(col).removeClass('moving');
});
};
[].forEach.call(cols_, function (col) {
col.setAttribute('draggable', 'true'); // Enable columns to be draggable.
col.addEventListener('dragstart', this.handleDragStart, false);
col.addEventListener('dragenter', this.handleDragEnter, false);
col.addEventListener('dragover', this.handleDragOver, false);
col.addEventListener('dragleave', this.handleDragLeave, false);
col.addEventListener('drop', this.handleDrop, false);
col.addEventListener('dragend', this.handleDragEnd, false);
});
});
.column {
height: 150px;
width: 150px;
float: left;
border: 2px solid #666666;
background-color: #ccc;
margin-right: 5px;
border-radius: 10px;
box-shadow: inset 0 0 3px #000;
text-align: center;
cursor: move;
margin-bottom: 30px;
}
.column header {
color: #fff;
text-shadow: #000 0 1px;
box-shadow: 5px;
padding: 5px;
background: linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21));
border-bottom: 1px solid #ddd;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.column {
transition: transform 0.2s ease-out;
}
.column.over {
border: 2px dashed #000;
}
.column.moving {
opacity: 0.25;
transform: scale(0.8);
}
.column .count {
padding-top: 15px;
font-weight: bold;
text-shadow: #fff 0 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class="cols">
<div class="column">
<header>C</header>
</div>
<div class="column">
<header>B</header>
</div>
<div class="column">
<header>A</header>
</div>
</div>
看起来供应商正在准备多个项目的拖放,但似乎没有默认设置。如果我错了,请纠正我。
我阅读了这些文章以更好地理解dnd
- https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_and_drop
- http://html5doctor.com/native-drag-and-drop/
进一步阅读:
dragstart
上自己将这些元素添加到列表中是很自然的。 - a better oliversetData
。我个人将数据存储在外部(例如变量中)。这使我拥有所有自由,并且最终数据来自何处并不重要。您可以使用setData
发送带有 ID 的序列化对象或数组(JSON.stringify / JSON.parse)。 - a better oliver