It seems the HTML5 attribute draggable
, which applies to one element says: "You can drag me, but you'd need multiple input devices to select another draggable element at the same time."
As a workaround one can add identifiers to selected elements using js and get all selected elements on a certain event and do what we want. But is this really the "correct" way?
When you inspect the drop
event there is an interface for multiple files, when handling file drag and drop. And there is also the items
property- at least in Chrome.
There are differences across browsers.
The drop
event contains the items
property
dataTransfer: DataTransfer
items: DataTransferItemList
length: 0
Items
seems to be 0, no matter if you dragged an item or not.
The drop
event contains the mozItemCount
property
dataTransfer: DataTransfer
mozItemCount: 1
mozItemCount
seems to be at least 1.
Where you can observe your developer tools console:
This source was taken from here: 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>
So it looks like the vendors are preparing for multiple item drag and drop, but there seems no be no default. Please correct me if i'am wrong.
I read these articles to better understand dnd
Further readings:
DataTransferItemList
Press and hold the Control Key (on the keyboard). While holding the Ctrl Key, select another file. Repeat step 2 until all the required files are selected. Note: It is important to keep the Ctrl Key pressed to ensure all files are highlighted.
The ondrop attribute fires when a draggable element or text selection is dropped on a valid drop target. Drag and drop is a very common feature in HTML5. It is when you "grab" an object and drag it to a different location. For more information, see our HTML Tutorial on HTML5 Drag and Drop.
First of all, the items
length as well as files
length is working in Chrome. You always get 0 length because the info in the drag data store is protected, except on drop event. So when you log the object and look at it afterwards, you don't have access to the info. But if you log it like this:
console.log(e.dataTransfer.items.length);
Then you'll have access to the actual length. See here regarding protected mode
:
https://html.spec.whatwg.org/multipage/interaction.html#the-drag-data-store
That is not to say that it'll give you the count of dragged elements, and there are a few reasons as to why:
First thing is that the native drag and drop API
is also used for
dragging from the browser to other applications and vice versa. So
lots of the features in there deal with these cases.
Other thing is that drag and drop API gives you access to things that are defaults behaviors of the browser in regard to dragging things. For example, dragging a link in your browser will open the link. When you use the API, you're accessing these behaviors.
Many behaviors of this API are a consequence of this and in that sense are not really intended to drag DOM elements around. To this purpose, other libraries are probably more appropriate or simply managing the content itself through the different events it offers.
Since you can drag and drop elements from other applications, a lot of the info has to do with this. For example in dataTransferItem
, you have access to a fileList
object. This is only working when dragging files from your OS into the browser. So you have a count of files, and the different files dragged. But this has nothing to do with dragging of DOM elements
.
You can also drag from the browser. Very useful for example if you want to drag HTML content to Word. But then the info to transfer is more complex than simply the DOM elements. In that case you're dragging items
, but these items
are not the DOM elements per say. They are the different types of things that can be transfered.
The types of things that can be transfered varies a lot in implementation, but basically you can have plain text, html content and links. So the length of the items will be the length of types available. For example, in the jsfiddle below, on Chrome, you can drag images, links and plain text(for this one you need to select only the text). Result of :
console.log(e.dataTransfer.items.length,
e.dataTransfer.getData('text/plain'),
e.dataTransfer.getData('text/uri-list'),
e.dataTransfer.getData('text/html'));
when draggin each element on the grey target is this:
Plain text from the input :
length: 1
plain text: text
link:
html content:
From image:
length: 2
plain text:
link: http://www.exiv2.org/include/img_1771.jpg
html content: <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"><img id="image1" src="http://www.exiv2.org/include/img_1771.jpg">
From link:
length: 3
plain text: http://google.com/
link: http://google.com/
html content: <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"><a href="http://google.com/">link 1</a>
See here: http://jsfiddle.net/ztj6t2ff/9/
You'll see that the html
is not exactly what you have on your page. This is to allow transfer to other applications and keep the best formatting possible.
So in general, this API
allows you to interfere with default behaviors of dragging almost anything you can drag in your OS in and from the browser. In that sense it's pretty complex, but most of the features have nothing to do with dragging DOM elements inside a same page.
And in fact almost all DOM manipulations through drag and drop are made without using this API. jquery-ui draggable
for example doesn't rely at all on this API.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With