Showcasing how to use the native HTML5 Drag and Drop API to move items on a page. Move the different broken up pieces of internet explorer back together to see the message!
A Pen by Simon Codrington on CodePen.
<article class="page"> | |
<article class="main"> | |
<h1>Native Drag and Drop - Data transfer on a single page</h1> | |
<h3>Shows how data can be transfered from one location to another on a single page</h3> | |
<p>Drag the 4 different pieces of Internet Explorer from the left container to the right container. The image data will be carried via the native API and processed on the drop zone. (If you are using Internet Explorer it will use jQuery to copy the node | |
as a fallback)</p> | |
<p>If your piece lands in the correct place it will be highlighted green, else it will be highlighted red. Once you have the puzzle correct you will get the completed message </p> | |
<h4 class="ie-message">You appear to be on Internet Explorer. IE doesn't support the 'text/html' type (only the 'text' and 'URL' types) so jQuery will be used to copy the dragged item instead of the API (instead of copying the HTML)</h4> | |
<article class="dnd-image-drag cf"> | |
<div class="container"> | |
<h3>Drag the puzzle pieces below</h3> | |
<div class="inner gallery-list cf"> | |
<img draggable="true" src="http://tinyurl.com/omdwmau" class="drag" data-value="2" /> | |
<img draggable="true" src="http://tinyurl.com/q4pnwfs" class="drag" data-value="3" /> | |
<img draggable="true" src="http://tinyurl.com/o7k8ezu" class="drag" data-value="1" /> | |
<img draggable="true" src="http://tinyurl.com/p3edsdp" class="drag" data-value="4" /> | |
</div> | |
</div> | |
<div class="container"> | |
<h3>Drop puzzle pieces here</h3> | |
<div class="inner gallery-painting cf"> | |
<div class="drop" data-value="1"></div> | |
<div class="drop" data-value="2"></div> | |
<div class="drop" data-value="3"></div> | |
<div class="drop" data-value="4"></div> | |
</div> | |
<div class="message-container"></div> | |
</div> | |
<div class="reset-button">Reset Example</div> | |
</article> | |
</article> | |
</article> |
Showcasing how to use the native HTML5 Drag and Drop API to move items on a page. Move the different broken up pieces of internet explorer back together to see the message!
A Pen by Simon Codrington on CodePen.
jQuery(document).ready(function($) { | |
//check for ie | |
var userAgent = window.navigator.userAgent; | |
if (userAgent.indexOf('MSIE') != -1) { | |
$('.ie-message').show(); | |
} | |
var drag_items = $('.dnd-image-drag .drag'); | |
var drop_items = $('.dnd-image-drag').find('.drop'); | |
//set up 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 = 'copy'; | |
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 = 'copy'; | |
$(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 = 'copy'; | |
$(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'); | |
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); | |
//check if this element is in the right spot | |
checkCorrectDrop(drop, dragItem); | |
//see if the final image is complete | |
checkCorrectFinalImage(); | |
} | |
//only have access to text (old browsers + IE) | |
else { | |
$(drop).empty(); | |
$(drop).prepend($(dragItem).clone()); | |
//check if this element is in the right spot | |
checkCorrectDrop(drop, dragItem); | |
//see if the final image is complete | |
checkCorrectFinalImage(); | |
} | |
event.preventDefault(); | |
event.stopPropagation(); | |
} | |
//check to see if this dropped item is in the correct spot | |
function checkCorrectDrop(drop, dragItem) { | |
//check if this drop is correct | |
var imageValue = $(dragItem).attr('data-value'); | |
var dropValue = $(drop).attr('data-value'); | |
if (imageValue == dropValue) { | |
$(drop).removeClass('incorrect').addClass('correct'); | |
} else { | |
$(drop).removeClass('correct').addClass('incorrect'); | |
} | |
} | |
//checks to see if the dropped images are in the correct locations | |
function checkCorrectFinalImage() { | |
var correctItems = drop_items.filter('.correct'); | |
if (correctItems.length == drop_items.length) { | |
$('.message-container').empty(); | |
$('.message-container').append('<h3>You solved the puzzle!</h3>'); | |
$('.message-container').append('<p>Thanks for putting Internet Explorer back together again!</p>'); | |
$('.message-container').append('<img src="http://tinyurl.com/nlftsar"/>'); | |
} else { | |
$('.message-container').empty(); | |
} | |
} | |
//Reset the drop containers | |
$('.reset-button').on('click', function() { | |
$('.dnd-image-drag').find('.drop').children('img').remove(); | |
$('.dnd-image-drag').find('.drop').removeClass('correct incorrect'); | |
$('.message-container').empty(); | |
}); | |
}); |
<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; | |
} | |
.page{ | |
max-width: 1200px; | |
margin: 0px auto; | |
} | |
/*drag and drop styles*/ | |
.dnd-image-drag .container { | |
width: 48%; | |
float: left; | |
margin: 0% 1% 2% 1%; | |
} | |
.dnd-image-drag .gallery-list { | |
min-height: 300px; | |
width: 350px; | |
background: #eee; | |
border: solid 1px #ccc; | |
padding: 15px 0px 15px 15px; | |
} | |
.dnd-image-drag .gallery-list .drag { | |
width: 150px; | |
float: left; | |
display: inline-block; | |
height: 150px; | |
border: solid 1px #ccc; | |
margin: 0px 15px 15px 0px; | |
cursor: -webkit-grab; | |
cursor: -moz-grab; | |
border: solid 1px transparent; | |
} | |
.dnd-image-drag .gallery-list .drag.drag-active { | |
border: solid 1px #2c3e50; | |
} | |
.dnd-image-drag .gallery-painting { | |
min-height: 300px; | |
width: 350px; | |
background: #eee; | |
background-image: url('./female.jpg'); | |
background-position: center center; | |
background-size: cover; | |
border: solid 1px #ccc; | |
padding: 15px 0px 15px 15px; | |
} | |
.dnd-image-drag .gallery-painting .drop { | |
position: relative; | |
height: 150px; | |
width: 150px; | |
background: rgba(50, 50, 50, 0.7); | |
display: inline-block; | |
border: solid 1px #eee; | |
float: left; | |
margin: 0px 15px 15px 0px; | |
border: solid 1px transparent; | |
overflow: hidden; | |
} | |
.dnd-image-drag .gallery-painting .drop.drop-active { | |
border: solid 1px #f1c40f; | |
} | |
.dnd-image-drag .gallery-painting .drop.correct { | |
border: solid 1px #32ce74; | |
} | |
.dnd-image-drag .gallery-painting .drop.incorrect { | |
border: solid 1px #c0392b; | |
} | |
.dnd-image-drag .gallery-painting .drop img { | |
max-width: 100%; | |
height: auto; | |
} | |
.reset-button { | |
background: #eee; | |
border: solid 1px #ccc; | |
padding: 12px 15px; | |
display: inline-block; | |
cursor: pointer; | |
margin-top: 25px; | |
} | |
.ie-message { | |
display: none; | |
padding: 15px; | |
background: #e74c3c; | |
color: #fff; | |
border: dashed 2px #c0392b; | |
margin-bottom: 15px; | |
} |
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,600,700,300" rel="stylesheet" /> |