Hello stackoverflow comunity.
I am working on some code that makes draggable resizeable divs. I have it working with the divs that are created originally, but the newly added divs arent becomming draggable.
Here is ALL my code:
<html>
<head>
<script>
var id = 4;
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev)
{
ev.preventDefault();
ev.target.appendChild(document.getElementById(ev.dataTransfer.getData("Text")));
}
function change(div)
{
var divw=parseInt(div.style.width);
var divh=parseInt(div.style.height);
var imgw=divw-10;
var imgh=divh-10;
div.children[0].style.width=imgw;
div.children[0].style.height=imgh;
div.style.border="dotted 3px grey";
}
function addimg()
{
var main = document.getElementById('main');
var div = document.createElement('div');
div.onmouseout = function() {this.style.border=0};
div.ondragstart = function() {drag(event)};
div.onmousemove = function() {change(this)};
div.setAttribute('draggable', true);
div.id = 'div'+id;
id+=1;
div.style.styleFloat = 'left';
div.style.cssFloat = 'left';
div.style.resize = 'both';
div.style.overflow = 'hidden';
div.style.height = '110px';
div.style.width = '110px';
div.innerHTML = '<img draggable="false" style="width: 100px; height: 100px" src="https://www.google.com/images/srpr/logo11w.png" />';
main.appendChild(div);
}
</script>
</head>
<body>
<center>
<div ID="main" ondragover="event.preventDefault()" ondrop="drop(event)" style="width:900px; height:900px; border: dashed 1px lightgrey;" overflow="auto">
<div onmouseout="this.style.border=0" draggable="true" ondragstart="drag(event)" onmousemove="change(this)" id="div1" style="float:left; resize:both; overflow:hidden; height: 110px; width:110px">
<textarea onblur="this.nextElementSibling.innerHTML=this.innerHTML" style="resize:none; width: 100px; height: 100px"></textarea>
<p style="background-color: blue"></p>
</div>
<div style="clear:both"></div>
<div onmouseout="this.style.border=0" draggable="true" ondragstart="drag(event)" onmousemove="change(this)" id="div2" style="float:left; resize:both; overflow:hidden; height: 110px; width:110px">
<img draggable="false" style="width: 100px; height: 100px" src="https://www.google.com/images/srpr/logo11w.png" />
</div>
<div onmouseout="this.style.border=0" draggable="true" ondragstart="drag(event)" onmousemove="change(this)" id="div3" style="float:left; resize:both; overflow:hidden; height: 110px; width:110px">
<img draggable="false" style="width: 100px; height: 100px" src="https://www.google.com/images/srpr/logo11w.png" />
</div>
</div>
</center>
<button onclick="addimg()">add an image</button>
</body>
</html>
the issue is that the new divs aren't draggable.
P.S. if you use jquery, please explain it very detailed, i have no experience with it.
I m not sure what draggable function in this case is. Is it just dragging this newly added image to this element in top left ? After what that image disappear ?
If this is case, solution is very simple. In function addimage you have wrong line.Your line is:
div.ondragstart = function() {drag(event)};
And it should be
div.ondragstart = function(event) {drag(event)};
In this line you call function without setting event as argument, and you use it in function.
Hope it helps.
One solution is to use the same method used to create the <img> element, to create the <div>:
<html>
<head>
<script>
var id = 4;
function drag(ev) {
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev) {
ev.preventDefault();
document.getElementById('main')
.appendChild(document.getElementById(ev.dataTransfer.getData("Text")));
}
function change(div) {
var divw = parseInt(div.style.width);
var divh = parseInt(div.style.height);
var imgw = divw - 10;
var imgh = divh - 10;
div.children[0].style.width = imgw;
div.children[0].style.height = imgh;
div.style.border = "dotted 3px grey";
}
function addimg() {
var main = document.getElementById('main');
main.innerHTML += '<div id="div'+id+'" onmouseout="this.style.border=0" draggable="true" ' +
'ondragstart="drag(event)" onmousemove="change(this)" style="float:left; ' +
'resize:both; overflow:hidden; height: 110px; width:110px"></div>';
div = document.getElementById('div'+id);
div.innerHTML = '<img draggable="false" style="width: 100px; height: 100px" src="https://www.google.com/images/srpr/logo11w.png" />';
id+=1;
}
</script>
</head>
<body>
<center>
<div ID="main" ondragover="event.preventDefault()" ondrop="drop(event)" style="width:900px; height:900px; border: dashed 1px lightgrey;" overflow="auto">
<div onmouseout="this.style.border=0" draggable="true" ondragstart="drag(event)" onmousemove="change(this)" id="div1" style="float:left; resize:both; overflow:hidden; height: 110px; width:110px">
<textarea onblur="this.nextElementSibling.innerHTML=this.innerHTML" style="resize:none; width: 100px; height: 100px"></textarea>
<p style="background-color: blue"></p>
</div>
<div style="clear:both"></div>
<div onmouseout="this.style.border=0" draggable="true" ondragstart="drag(event)" onmousemove="change(this)" id="div2" style="float:left; resize:both; overflow:hidden; height: 110px; width:110px">
<img draggable="false" style="width: 100px; height: 100px" src="https://www.google.com/images/srpr/logo11w.png" />
</div>
<div onmouseout="this.style.border=0" draggable="true" ondragstart="drag(event)" onmousemove="change(this)" id="div3" style="float:left; resize:both; overflow:hidden; height: 110px; width:110px">
<img draggable="false" style="width: 100px; height: 100px" src="https://www.google.com/images/srpr/logo11w.png" />
</div>
</div>
</center>
<button onclick="addimg()">add an image</button>
</body>
</html>
This should ensure the browser renders the new <div> element in the same way as the existing ones. In addition ensuring that elements are appended back to the main <div> element when they are dropped, will prevent them from disappearing when dropped onto of other elements, as previously.
Using Jquery
On the tip of using jquery, if we include the jquery.min.js library at the top of the file:
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
The change() function can be rewritten as:
function change(div) {
var $div = $(div);
$div.css('border','dotted 3px grey')
.children( ':first' )
.width( $div.width() - 10 )
.height( $div.height() - 10 );
}
This is somewhat shorter than the original. The first line converts the div parameter into a jquery object and stores it in the $div variable. The $ at the beginning of the variable name is just a convention, as the variable contains a jquery object. Caching the jquery object in this variable is more efficient than using $(div) 3 times in the change() function.
Calls to$div.width() and $div.height() perform the same action as the parseInt() calls in the original function. Jquery allows function calls to be 'chained', thus the first call on $div sets the border style and returns the same $div object. The .children() call returns the first child of $div (the <img> element) which then has it's width and height set using the corresponding methods.
It should be noted that jquery is generally thought to be easier to use, and offer good cross browser compatibility (which can be a real headache) rather than more efficient.
Moving style out of elements
We can move the common style attribute out of the individual elements into a separate section in the <head> of the html:
<style>
#main {
width:900px;
height:900px;
border: dashed 1px lightgrey;
overflow: auto;
}
.dragDiv {
float: left;
resize: both;
overflow: hidden;
height: 110px;
width: 110px;
}
.dragDiv img {
width: 100px;
height: 100px
}
.dragDiv textarea {
resize: none;
width: 100px;
height: 100px;
}
</style>
By giving the drag-able <div> elements the class dragDiv we reduce the amount of style duplication:
<div id="main" ondragover="event.preventDefault()" ondrop="drop(event)">
<div class="dragDiv" onmouseout="this.style.border=0" draggable="true" ondragstart="drag(event)" onmousemove="change(this)" id="div1">
<textarea onblur="this.nextElementSibling.innerHTML=this.innerHTML"></textarea>
<p style="background-color: blue"></p>
</div>
<div style="clear:both"></div>
<div class="dragDiv" onmouseout="this.style.border=0" draggable="true" ondragstart="drag(event)" onmousemove="change(this)" id="div2">
<img draggable="false" src="https://www.google.com/images/srpr/logo11w.png" />
</div>
<div class="dragDiv" onmouseout="this.style.border=0" draggable="true" ondragstart="drag(event)" onmousemove="change(this)" id="div3">
<img draggable="false" src="https://www.google.com/images/srpr/logo11w.png" />
</div>
</div>
Is this something like what you are looking for? I'm happy to suggest more alterations, if required.
Jquery offers draggables - which use absolute positioning; resizables; and sortables - which offer similar 'snap on drop' behaviour as the code above. Although I don't suggest you use these instead, they might be good guides as to how you wish your code to behave.
Related
I am working on a webpage for a class assignment. We are to utilize the HTML5 API drag and drop, which has been successfully implemented. I wanted to go a step further with the drag and drop API by incorporating some JavaScript to change a line of text on the webpage. I anticipated this line of text to be able to change into different statements based on which draggable object was dropped. I was able to achieve a single change to the text, but I was unable to find a way to have the text change to a different message. I consulted with my professor about this and she recommended I ask the question in these forums to find out more information. Is there a way to achieve this effect with the HTML5 API?
The code I started with to get the initial change in text looks like this:
<body>
<main>
<h2 class="center">What are Specializations?</h2>
<p class="center">Specializations in Project Management are similar to certifications, but instead highlight expertise on specific management approaches, task oversight, and industries. </p>
<br>
<br>
<h2 class="center">What Specializations are available?</h2>
<p class="center" id="demo">(Drag and Drop the specializations into the box for more details)</p>
<br>
<br>
<div class="container" style="background-color: #fafad2;">
<div></div>
<div></div>
<div draggable="true" class="box" style="background-color: #AFFF7A; border-color: #000000; padding: 20%;"></div>
<div></div>
<div></div>
</div>
<br>
<div class="container">
<div draggable="true" class="box">PMI-RMP</div>
<div draggable="true" class="box">PMI-SP</div>
<div draggable="true" class="box">AHPP</div>
<div draggable="true" class="box">AM-MC</div>
<div draggable="true" class="box">CD-P</div>
<div draggable="true" class="box">CDBA</div>
<div draggable="true" class="box">BEPC</div>
<div draggable="true" class="box">BEPM</div>
<div draggable="true" class="box">BETI</div>
<div draggable="true" class="box">PMI-CP</div>
<div draggable="true" class="box">OTF</div>
<div draggable="true" class="box">OTI</div>
<div draggable="true" class="box">OTO</div>
</div>
<script>
/* Events fired on the drag target */
document.addEventListener("dragstart", function(event) {
// The dataTransfer.setData() method sets the data type and the value of the dragged data
event.dataTransfer.setData("Text", event.target.id);
});
// Output some text when finished dragging the p element and reset the opacity
document.addEventListener("dragend", function(event) {
document.getElementById("demo").innerHTML = "Finished dragging the p element.";
});
/* Events fired on the drop target */
// By default, data/elements cannot be dropped in other elements. To allow a drop, we must prevent the default handling of the element
document.addEventListener("dragover", function(event) {
event.preventDefault();
});
</script>
</main>
</body>
I would then approach the multi-message display by using a JavaScript event listener and if-else statements, seen in this code:
<body>
<main>
<h2 class="center">What are Specializations?</h2>
<p class="center">Specializations in Project Management are similar to certifications, but instead highlight expertise on specific management approaches, task oversight, and industries. </p>
<br>
<br>
<h2 class="center">What Specializations are available?</h2>
<p class="center" id="demo">(Drag and Drop the specializations into the box for more details)</p>
<br>
<br>
<div class="container" style="background-color: #fafad2;">
<div></div>
<div></div>
<div draggable="true" class="box" style="background-color: #AFFF7A; border-color: #000000; padding: 20%;"></div>
<div></div>
<div></div>
</div>
<br>
<div class="container">
<div draggable="true" class="box">PMI-RMP</div>
<div draggable="true" class="box">PMI-SP</div>
<div draggable="true" class="box">AHPP</div>
<div draggable="true" class="box">AM-MC</div>
<div draggable="true" class="box">CD-P</div>
<div draggable="true" class="box">CDBA</div>
<div draggable="true" class="box">BEPC</div>
<div draggable="true" class="box">BEPM</div>
<div draggable="true" class="box">BETI</div>
<div draggable="true" class="box">PMI-CP</div>
<div draggable="true" class="box">OTF</div>
<div draggable="true" class="box">OTI</div>
<div draggable="true" class="box">OTO</div>
</div>
<script>
/* Events fired on the drag target */
document.addEventListener("dragstart", function(event) {
// The dataTransfer.setData() method sets the data type and the value of the dragged data
event.dataTransfer.setData("Text", event.target.id);
});
// Output some text when finished dragging the p element and reset the opacity
document.addEventListener("dragend", function(event) {
document.getElementById("definition").innerHTML = "(Drag and Drop the specializations into the box for more details)";
var id='1';
if (id=='1') {
document.getElementById("definition").innerHTML = "This is definition 1";
}else if (id=='2'){
document.getElementById("definition").innerHTML = "This is definition 2";
}else if (id=='3'){
document.getElementById("definition").innerHTML = "This is definition 3";
}else (id=='4'){
document.getElementById("definition").innerHTML = "This is definition 4";
}
});
/* Events fired on the drop target */
// By default, data/elements cannot be dropped in other elements. To allow a drop, we must prevent the default handling of the element
document.addEventListener("dragover", function(event) {
event.preventDefault();
});
</script>
</main>
</body>
The CSS utilized:
body {
background-color:#fafad2;
margin: 3%;
}
h1 {
color:#4169E1;
font-family: "Trebuchet MS";
font-size: 300%;
opacity: 75%;
text-shadow: 1px -2px 1px #00008B;
}
h2 {
color:#4682B4;
font-family: "Trebuchet MS";
font-size: 200%;
}
h3 {
color:#B0C4DE;
font-family: "Trebuchet MS";
font-size: 150%;
font-style: italic;
}
main {
padding: 4%;
}
p {
font-family: Georgia;
}
.container {
background-color: #FFFF76;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-gap: 1%;
padding: 1%;
}
.box {
border: 3px solid #ddd;
background-color: #FFF5EE;
padding: 10%;
margin: 5%;
cursor: move;
text-align: center;
}
.box.over {
border: 4px dashed #666;
}
I'm trying to make a website that use drag and drop functionality to build a website. But I'm facing the problem that the element is not being append before another element like the code I have shown. please help me so it can drop the elements before and after a specific element not just at the end of all the elements.
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
#div1,
#div2 {
float: left;
width: 500px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
<h2>Drag and Drop</h2>
<p>Drag the image back and forth between the two div elements.</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<button draggable="true" ondragstart="drag(event)" id="drag1">button1</button>
<button draggable="true" ondragstart="drag(event)" id="drag2">button2</button>
<button draggable="true" ondragstart="drag(event)" id="drag3">button3</button>
<button draggable="true" ondragstart="drag(event)" id="drag4">button4</button>
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">
</div>
I'm using javascript.
That's actually quite tricky to achieve, you need to implement your own logic for inserting the element to the correct position in the list.
Here is an example where you can move items between divs and reorder items in the same div
(Note that I only implemented the logic for drag/drop items horizontally in a single line by using left offset, if you have multiple lines items list, you need to implement your own)
function allowDrop(ev) {
ev.preventDefault()
}
function drag(ev) {
ev.dataTransfer.setData('text', ev.target.id)
}
function drop(ev) {
ev.preventDefault()
var data = ev.dataTransfer.getData('text')
// ev.currentTarget is the div that the elements are dropped
const currentDragElementOffset = ev.clientX
const items = ev.currentTarget.children
//empty list, just append and return
if (items.length === 0) {
ev.currentTarget.appendChild(document.getElementById(data))
return
}
// non-empty list
for (let i = 0; i < items.length; i++) {
const item = items[i]
const {
left,
width
} = item.getBoundingClientRect()
// find the offset left from the center of the item
const currentElementLeftOffset = left + width / 2;
if (currentDragElementOffset < currentElementLeftOffset) {
ev.currentTarget.insertBefore(document.getElementById(data), item)
return
}
// found no insertion point, that means item was dragged to the end of the list
if (i === items.length - 1 && currentDragElementOffset > currentElementLeftOffset) {
ev.currentTarget.appendChild(document.getElementById(data))
}
}
}
#div1,
#div2 {
float: left;
width: 500px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
<!DOCTYPE html>
<html>
<body>
<h2>Drag and Drop</h2>
<p>Drag the image back and forth between the two div elements.</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<button draggable="true" ondragstart="drag(event)" id="drag1">
button1
</button>
<button draggable="true" ondragstart="drag(event)" id="drag2">
button2
</button>
<button draggable="true" ondragstart="drag(event)" id="drag3">
button3
</button>
<button draggable="true" ondragstart="drag(event)" id="drag4">
button4
</button>
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</body>
</html>
Simply use the CSS property order.
The drop zones must have display: flex or display: inline-flex (see .zone in Example - CSS)
Each item that is draggable should have style="order: number " (see Example - JS)
Also, to avoid an item appending to another item, use event.currentTarget instead of event.target in the drop() function (see drop() in Example - JS). In the example, the repetitive parts in HTML have been streamlined (see Figure I):
Figure I
Original Post
Example
Attributes on each element in HTML
Attributes assigned to each element by .forEach()
Inline events on each element in HTML
Onevent properties bound to each element by .forEach()
Example
Details are commented
/*
Collect all .btn into a NodeList
Iterate through NodeList with .forEach()
Bind dragstart event to current <button>
Add inline style "order" with the value of current index
Add "draggable" attribute with the value of true
*/
document.querySelectorAll('.btn').forEach((b, i) => {
b.ondragstart = drag;
b.style.order = i;
b.setAttribute('draggable', true);
});
/*
Collect all .zone into a NodeList
Iterate through NodeList with .forEach()
Bind drop event to current <div>
Bind dragover event to current <div>
*/
document.querySelectorAll('.zone').forEach(z => {
z.ondrop = drop;
z.ondragover = allowDrop;
});
function allowDrop(e) {
e.preventDefault();
}
function drag(e) {
e.dataTransfer.setData("text", e.target.id);
}
function drop(e) {
e.preventDefault();
let data = e.dataTransfer.getData("text");
/*
Change e.target to e.currentTarget to prevent any <button>
appending onto another <button>. e.currentTarget will always
point to .zone
*/
e.currentTarget.append(document.getElementById(data));
}
.zone {
display: flex;
align-items: center;
width: 500px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
.btn {
margin: 0 10px;
cursor: move;
}
<h2>Drag and Drop</h2>
<p>Drag the buttons back and forth between the two div elements.</p>
<div class="zone">
<button id='b1' class='btn'>button1</button>
<button id='b2' class='btn'>button2</button>
<button id='b3' class='btn'>button3</button>
<button id='b4' class='btn'>button4</button>
</div>
<div class="zone"></div>
You should use .prepend() method for inserting element before the other element.
Element.prepend() method inserts a set of Node objects or string objects before the first child of the Element. String objects are inserted as equivalent Text nodes.
Here's a Working Code :
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.prepend(document.getElementById(data));
}
#div1,
#div2 {
float: left;
width: 500px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
<h2>Drag and Drop</h2>
<p>Drag the image back and forth between the two div elements.</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<button draggable="true" ondragstart="drag(event)" id="drag1">button1</button>
<button draggable="true" ondragstart="drag(event)" id="drag2">button2</button>
<button draggable="true" ondragstart="drag(event)" id="drag3">button3</button>
<button draggable="true" ondragstart="drag(event)" id="drag4">button4</button>
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">
</div>
I have image that I want to drag and drop infinitely.From first box to second box when I move,image disappear from first box.Not to lose image created same image on first box again using .appendchild(img) method.I want to drag image from initial position,not from where I dropped.So I changed draggable property as false when I dropped image into box.It creates image on first box,there's no problem.But I can't drag and drop it from first box to third again because that image has no event properties.I want to give them those properties again and it should be repeated because I want to do it forever.
Here's what I tried
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1, #div2,#div3 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
</style>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
var img = document.createElement("img");
img.src = "https://mikasasports.com/wp-content/uploads/2015/04/MVA2001.png";
var src = document.getElementById("div1");
img.style.width="88px";
img.style.height="31px";
src.appendChild(img);
drag1.draggable=false;
}
</script>
</head>
<body>
<h2>Drag and Drop</h2>
<p>Drag the image back and forth between the three div elements.</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="https://mikasasports.com/wp-content/uploads/2015/04/MVA2001.png" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div3" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</body>
</html>
Ok I have 7 colour block in which to drag 7 colour names. If the user get the correct colour name in the right colour block they receive a point. This is my code below but my count is not working when the user gets the correct answer. Can anyone help please, I know it is something stupid I'm not seeing.
function readDropZone() {
var score = document.getElementById('score');
score.innerHTML = 0;
var block = document.getElementById('colour-block').children;
for(var i = 0; i < block.length; ++i) {
var hitblock = block[i];
var dropzone = hitblock.lastElementChild;
if (dropzone.children.length > 0) {
var dropzoneId = dropzone.id;
var blockId = dropzone.firstElementChild.id;
var blockNo = dropzoneId.substring(dropzoneId.indexOf('-') + 1);
var dragNo = blockId.substring(blockId.indexOf('-') + 1);
if (dragNo == blockNo) {
score.innerHTML = parseInt(score.innerHTML) + 1;
}
}
if (parseInt(score.innerHTML) == 10) {
alert('Congratulations! You won the game!\nClick OK to restart.');
location.reload();
}
}
}
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
readDropZone();
const data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
#block-1, #block-2, #block-3, #block-4, #block-5, #block-6, #block-7 {
color: #fff;
width: 150px;
height: 35px;
border: 1px solid #aaaaaa;
text-align: center;
padding: 10px 0;
font-size: 1.25em;
}
#block-3 {
color: #000;
}
#colour-block {
float: left;
width: 50%;
}
#colour-name {
float: right;
line-height: 1.5em;
font-size: 1.25em;
font-weight: bold;
width: 50%;
clear: right;
cursor: move;
}
<h2>1. Drag and drop the names into the coloured blocks</h2>
<div id="colour-block">
<div id="block-1" class="block" style="background-color:red" ondrop="drop(event)" ondragover="allowDrop(event)" name="red"></div>
<div id="block-2" class="block" style="background-color:orangered" ondrop="drop(event)" ondragover="allowDrop(event)" name="orange" ></div>
<div id="block-3" class="block" style="background-color:yellow" ondrop="drop(event)" ondragover="allowDrop(event)" name="yellow"></div>
<div id="block-4" class="block" style="background-color:green" ondrop="drop(event)" ondragover="allowDrop(event)" name="green"></div>
<div id="block-5" class="block" style="background-color:skyblue" ondrop="drop(event)" ondragover="allowDrop(event)" name="blue"></div>
<div id="block-6" class="block" style="background-color:midnightblue" ondrop="drop(event)" ondragover="allowDrop(event)" name="indego"></div>
<div id="block-7" class="block" style="background-color:rgb(109, 92, 221)" ondrop="drop(event)" ondragover="allowDrop(event)" name="violet"></div>
</div>
<div id="colour-name">
<div id="drag-6" class="colour" draggable="true" ondragstart="drag(event)" name="indego">Indeagó</div>
<div id="drag-2" class="colour" draggable="true" ondragstart="drag(event)" name="orange">Oráiste</div>
<div id="drag-4" class="colour" draggable="true" ondragstart="drag(event)" name="green">Glas</div>
<div id="drag-3" class="colour" draggable="true" ondragstart="drag(event)" name="yellow">Buí</div>
<div id="drag-1" class="colour" draggable="true" ondragstart="drag(event)" name="red">Dearg</div>
<div id="drag-7" class="colour" draggable="true" ondragstart="drag(event)" name="violet">Corcairghorm</div>
<div id="drag-5" class="colour" draggable="true" ondragstart="drag(event)" name="blue">Gorm</div>
</div>
<div style="clear:both"></div>
<h1>Your score is <span id="score">0</span> out of 7</h1>
</div>
As several others have stated, your blockResults function is not being invoked. Once it is being invoked there are 2 errors that are preventing count from incrementing properly:
dropzone will never have children. You already check for the presense of children in this line: var dropzone = hitblock.lastElementChild; So I changed the if statement to just if (dropzone) {
The line var blockId = dropzone.firstElementChild.id; was a bit confusing to me as you are trying to get the id of the block but you are looking at the child's Id which is not present. I changed the line to var blockId = hitblock.id;
The counter begun incrementing after these two changes.
this is a school project. Making a 2x2 grid, pictures in 3 of them and the picture should be able to be moved from "box to box". Everything else is in order, except the lower 2 divs.
The top 2 are perfectly in line, but when trying to make the second one, they either come right next to the first ones (with a br so they're a bit lower), or then on top of each other under the first 2. I know it's not a big thing that i'm missing, but i just can't seem to figure it out.
#loota {
float: left;
width: 200px;
height: 283px;
border: 2px solid #aaaaaa;
}
#loota2 {
float: left;
width: 200px;
height: 283px;
border: 2px solid #aaaaaa;
}
<div id="loota" ondrop="tiputus(event)" ondragover="siirto(event)">
<img id="kuva1" src="https://placeholdit.imgix.net/~text?txtsize=33&txt=Placeholder&w=200&h=283" draggable="true" ondragstart="veto(event)" width="200" height="283">
</div>
<div id="loota" ondrop="tiputus(event)" ondragover="siirto(event)">
<img id="kuva2" src="https://placeholdit.imgix.net/~text?txtsize=33&txt=Placeholder&w=200&h=283" draggable="true" ondragstart="veto(event)" width="200" height="283">
</div>
<br>
<div id="loota2" ondrop="tiputus(event)" ondragover="siirto(event)">
<img id="kuva3" src="https://placeholdit.imgix.net/~text?txtsize=33&txt=Placeholder&w=200&h=283" draggable="true" ondragstart="veto(event)" width="200" height="283">
</div>
<div id="loota" ondrop="tiputus(event)" ondragover="siirto(event)"></div>
The 2x2grid can be created using css nth operators.
The drag and drop can be done on individual images with a class and an operator function:
(function closedScopeForDragAndDropImages() {
var dragTarget = null;
window.addEventListener("dragover", function(event) {
// prevent default to allow drop
event.preventDefault();
}, false);
window.addEventListener("drag", function(event) {
if (event.target.className == "dropable-image") {
dragTarget = event.target;
}
// prevent default to allow drop
event.preventDefault();
}, false);
window.addEventListener("drop", function(event) {
// prevent default action (open as link for some elements)
event.preventDefault();
// move dragged elem to the selected drop target
if (event.target.className == "dropable-image") {
var src = dragTarget.getAttribute("src");
dragTarget.setAttribute("src", event.target.getAttribute("src"));
event.target.setAttribute("src", src)
}
}, false);
})();
.tile {
float: left;
width: 200px;
height: 283px;
border: 2px solid #aaaaaa;
}
.tile:nth-child(2n+3) {
clear: left;
}
<div class="tile">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=Placeholder1&w=200&h=283" class="dropable-image" draggable="true" />
</div>
<div class="tile">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=Placeholder2&w=200&h=283" class="dropable-image" draggable="true" />
</div>
<div class="tile">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=Placeholder3&w=200&h=283" class="dropable-image" draggable="true" />
</div>
<div class="tile">
<img src="https://placeholdit.imgix.net/~text?txtsize=33&txt=Placeholder4&w=200&h=283" class="dropable-image" draggable="true" />
</div>