Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save simonrcodrington/d71ba910344ce078cd3d to your computer and use it in GitHub Desktop.
Save simonrcodrington/d71ba910344ce078cd3d to your computer and use it in GitHub Desktop.
Native Drag and Drop - the effectAllowed and the DropEffect properties
<article class="page">
<article class="main">
<h1>Native Drag and Drop - the effectAllowed and the DropEffect properties</h1>
<h3>Setting the correct effects will tell the API what is allowed to be dragged and to where</h3>
<p>Only draggable items that match the same effect as the drop zone will be allowed. This uses only the native HTML5 API to reject non applicable drags</p>
<article class="drop-effect cf">
<div class="container">
<p>Setting the effectAllowed tells the browser what is allowed with this draggable item. It also determines which cursor will be used when the draggable is hovered over a drop zone</p>
<div class="drag-zone cf">
<div class="drag-item">
<h4 class="clear">Copy</h4>
<img draggable="true" src="http://tinyurl.com/pb4w3ew" class="drag" data-effect-allowed="copy" />
</div>
<div class="drag-item">
<h4 class="clear">Link</h4>
<img draggable="true" src="http://tinyurl.com/pb4w3ew" class="drag" data-effect-allowed="link" />
</div>
<div class="drag-item">
<h4 class="clear">Move</h4>
<img draggable="true" src="http://tinyurl.com/pb4w3ew" class="drag" data-effect-allowed="move" />
</div>
<div class="drag-item">
<h4 class="clear">All</h4>
<img draggable="true" src="http://tinyurl.com/pb4w3ew" class="drag" data-effect-allowed="all" />
</div>
<div class="drag-item">
<h4 class="clear">None</h4>
<img draggable="true" src="http://tinyurl.com/pb4w3ew" class="drag" data-effect-allowed="none" />
</div>
<div class="drag-item">
<h4 class="clear">copyLink</h4>
<img draggable="true" src="http://tinyurl.com/pb4w3ew" class="drag" data-effect-allowed="copyLink" />
</div>
<div class="drag-item">
<h4 class="clear">linkMove</h4>
<img draggable="true" src="http://tinyurl.com/pb4w3ew" class="drag" data-effect-allowed="linkMove" />
</div>
<div class="drag-item">
<h4 class="clear">copyMove</h4>
<img draggable="true" src="http://tinyurl.com/pb4w3ew" class="drag" data-effect-allowed="copyMove" />
</div>
</div>
</div>
<div class="container">
<h3>Drag the image above in the various containers</h3>
<p>Depending on which item you drag, you may or may not be able to drop</p>
<div class="drop-zone cf">
<div class="drop-item">
<h4 class="clear">Copy</h4>
<p>I accept any element that specifies it will 'copy'</p>
<div class="drop" data-drop-effect="copy"></div>
</div>
<div class="drop-item">
<h4 class="clear">Link</h4>
<p>I accept any element that specifies it will 'link'</p>
<div class="drop" data-drop-effect="link"></div>
</div>
<div class="drop-item">
<h4 class="clear">Move</h4>
<p>I accept any element that specifies it will 'move'</p>
<div class="drop" data-drop-effect="move"></div>
</div>
<div class="drop-item">
<h4 class="clear">None</h4>
<p>I wont accept anything at all. Nothing</p>
<div class="drop" data-drop-effect="none"></div>
</div>
</div>
<div class="reset-button">Reset drag and drop</div>
</div>
</article>
</article>
</article>

Native Drag and Drop - the effectAllowed and the DropEffect properties

Displaying how the HTML5 Drag and Drop API can be used to control what elements can be dragged and where they can be dropped.

For additional information, please see my corresponding article on SitePoint

A Pen by Simon Codrington

License.

jQuery(document).ready(function($) {
var drag_items = $('.drop-effect .drag');
var drop_items = $('.drop-effect').find('.drop');
//sets up the drag and drop event listeners
function setUpEventListeners() {
drag_items.each(function() {
var thisDrag = $(this);
thisDrag[0].addEventListener('dragstart', dragStart);
thisDrag[0].addEventListener('drag', drag);
thisDrag[0].addEventListener('dragend', dragEnd);
});
drop_items.each(function() {
var thisDrop = $(this);
thisDrop[0].addEventListener('dragenter', dragEnter);
thisDrop[0].addEventListener('dragover', dragOver);
thisDrop[0].addEventListener('dragleave', dragLeave);
thisDrop[0].addEventListener('drop', drop);
});
}
setUpEventListeners();
var dragItem;
//called as soon as the draggable starts being dragged
//used to set up data and options
function dragStart(event) {
drag = event.target;
dragItem = event.target;
//set the effectAllowed for the drag item
event.dataTransfer.effectAllowed = $(this).attr('data-effect-allowed');
var imageSrc = $(dragItem).prop('src');
var imageHTML = $(dragItem).prop('outerHTML');
//check for IE (it supports only 'text' or 'URL')
try {
event.dataTransfer.setData('text/uri-list', imageSrc);
event.dataTransfer.setData('text/html', imageHTML);
} catch (e) {
event.dataTransfer.setData('text', imageSrc);
}
$(drag).addClass('drag-active');
}
//called as the draggable enters a droppable
//needs to return false to make droppable area valid
function dragEnter(event) {
var drop = this;
//set the drop effect for this zone
event.dataTransfer.dropEffect = $(this).attr('data-drop-effect');
$(drop).addClass('drop-active');
event.preventDefault();
event.stopPropagation();
}
//called continually while the draggable is over a droppable
//needs to return false to make droppable area valid
function dragOver(event) {
var drop = this;
//set the drop effect for this zone
event.dataTransfer.dropEffect = $(this).attr('data-drop-effect');
$(drop).addClass('drop-active');
event.preventDefault();
event.stopPropagation();
}
//called when the draggable was inside a droppable but then left
function dragLeave(event) {
var drop = this;
$(drop).removeClass('drop-active');
}
//called continually as the draggable is dragged
function drag(event) {}
//called when the draggable has been released (either on droppable or not)
//may be called on invalid or valid drop
function dragEnd(event) {
var drag = this;
$(drag).removeClass('drag-active');
}
//called when draggable is dropped on droppable
//final process, used to copy data or update UI on successful drop
function drop(event) {
drop = this;
$(drop).removeClass('drop-active');
$(drop).addClass('correct');
var dataList, dataHTML, dataText;
//collect our data (based on what browser support we have)
try {
dataList = event.dataTransfer.getData('text/uri-list');
dataHTML = event.dataTransfer.getData('text/html');
} catch (e) {;
dataText = event.dataTransfer.getData('text');
}
//we have access to the HTML
if (dataHTML) {
$(drop).empty();
$(drop).prepend(dataHTML);
}
//only have access to text (old browsers + IE)
else {
$(drop).empty();
$(drop).prepend($(dragItem).clone());
}
event.preventDefault();
event.stopPropagation();
}
//Reset the drop containers
$('.reset-button').on('click', function() {
$('.drop-zone').find('img').remove();
$('.drop-zone').find('.drop').removeClass('correct');
});
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
/*universal styling*/
html {
font-size: 62.5%;
}
body {
font-family: 'Open Sans', sans-serif;
font-weight: 400;
font-style: normal;
font-size: 1.5rem;
line-height: 1.5rem;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 600;
line-height: 150%;
margin: 1.5rem 0rem;
}
h1 {
font-size: 3.8rem;
margin: 2.85rem 0rem;
}
h2 {
font-size: 2.8rem;
margin: 2.1rem 0rem;
}
h3 {
font-size: 2.1rem;
margin: 1.57rem 0rem;
}
h4 {
font-size: 1.8rem;
}
h5 {
font-size: 1.3rem;
}
h6 {
font-size: 1.0rem;
}
p {
margin: 0rem 0rem 2.4rem 0rem;
line-height: 150%;
}
ul,
ol {
margin-left: 25px;
margin-bottom: 15px;
line-height: 150%;
}
/*clearfixes*/
.cf:before,
.cf:after {
content: " ";
display: table;
}
.cf:after {
clear: both;
}
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section,
div {
margin: 1.5rem 0rem;
}
div {
margin: 0rem;
}
.clear {
clear: both;
}
.page {
max-width: 960px;
margin: 0px auto;
}
.drop-effect .container {
width: 100%;
float: left;
margin: 0% 0% 5% 0%;
}
.reset-button {
background: #eee;
border: solid 1px #ccc;
padding: 12px 15px;
display: inline-block;
cursor: pointer;
margin-top: 25px;
}
/*universal*/
.drop-effect .drag-zone,
.drop-effect .drop-zone {
width: 100%;
background: #eee;
border: solid 1px #ccc;
padding: 15px 0px 15px 15px;
}
.drop-effect .drag-item,
.drop-effect .drop-item {
width: 25%;
float: left;
text-align: center;
overflow: hidden;
}
.drop-effect .drag-item .drag,
.drop-effect .drop-item .drop {
border: solid 1px #ccc;
background: #DDD;
cursor: -webkit-grab;
cursor: -moz-grab;
border: solid 1px transparent;
height: 150px;
width: 150px;
display: inline-block;
-webkit-transition: all 300ms ease-in;
-moz-transition: all 300ms ease-in;
-o-transition: all 300ms ease-in;
transition: all 300ms ease-in;
}
/*drag related styles*/
.drop-effect .drag-zone {}
.drop-effect .drag-zone .drag {}
.drop-effect .drag-zone .drag.drag-active {
border: solid 1px #333;
opacity: 0.7;
}
/*drop related styles*/
.drop-effect .drop-zone {}
.drop-effect .drop-zone .drop {}
.drop-effect .drop-zone .drop.drop-active {
border: solid 1px #AAA;
}
.drop-effect .drop-zone .drop.correct {
border: solid 1px #32ce74;
}
.drop-effect .drop-zone .drop img {
max-width: 100%;
height: auto;
}
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600,700,300" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment