I have simple table with two cells. I change w3 school code(for drag and drop) to one image, when drag over second, take second image place and second image disappears. But problem come when there is no image in cell, then cell is gone. How to check is there image in cell?
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");
var el = ev.target.parentNode;
ev.target.appendChild(document.getElementById(data));
el.appendChild(document.getElementById(data).cloneNode(true));
var x = el.classList.contains('dropzone');
if (!x) {
ev.target.remove();
}
}
th, td{
border: solid black;
width: 100px;
height: 100px;
padding: 0px;
}
table{
width: 300px;
}
img{
width: 100px;
}
<table>
<tr>
<td ondrop="drop(event)" ondragover="allowDrop(event)"><img ondragstart="drag(event)" draggable="true" id="a8" src="http://images5.fanpop.com/image/photos/27700000/desert-windows-7-vista-and-xp-picks-27752343-500-375.jpg"></td>
<td ondrop="drop(event)" ondragover="allowDrop(event)"><img ondragstart="drag(event)" draggable="true" id="b8" src="http://images5.fanpop.com/image/photos/27700000/jellyfish-windows-7-vista-and-xp-picks-27753183-500-375.jpg"></td>
</tr>
</table>
you can loop throught td elements and add ondrop event in you javascript code, So you can know which element has fired the event.
Then check if this element has a child inside.
If not => don't perform action (no image elements inside), else => perform action (there is an image elements inside).
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
var td=document.getElementsByTagName("td");
for(var i=0; i < td.length;i++){ //bind ondrop event to all td, so it will be easier to get the element which fired the event
td[i].ondrop=function(ev){
ev.preventDefault();
if (this.hasChildNodes()) { //check if got children nodes (if got img inside)
var data = ev.dataTransfer.getData("text");
var el = ev.target.parentNode;
ev.target.appendChild(document.getElementById(data));
el.appendChild(document.getElementById(data).cloneNode(true));
var x = el.classList.contains('dropzone');
if (!x) {
ev.target.remove();
}
}
}
}
th, td{
border: solid black;
width: 100px;
height: 100px;
padding: 0px;
}
table{
width: 300px;
}
img{
width: 100px;
}
<table>
<tr>
<td ondragover="allowDrop(event)"><img ondragstart="drag(event)" draggable="true" id="a8" src="http://images5.fanpop.com/image/photos/27700000/desert-windows-7-vista-and-xp-picks-27752343-500-375.jpg"></td>
<td ondragover="allowDrop(event)"><img ondragstart="drag(event)" draggable="true" id="b8" src="http://images5.fanpop.com/image/photos/27700000/jellyfish-windows-7-vista-and-xp-picks-27753183-500-375.jpg"></td>
</tr>
</table>
For more details how to check if element has any children, check answers here
Related
I have a piece of code that gets fixed while y-scoll is over 765px. The problem is that this content will be fixed even outside its parent. Here is an example: https://jsfiddle.net/rwbsua3v/
As you can see, while you keep scrolling, the content in the green box gets fixed and will override the blue box as you scroll.
I could fix this issue if I knew the exact heights of the red/green and blue boxes but the problem is that they can be of any length. How would I make the content in the green box fixed until it hits the bottom of parent (green box) without affecting the y-scroll offset and css top: 87px?
Here is my code:
window.onscroll = function() {
myFunction()
};
var floating1 = document.getElementById("floating1");
var yOffset = 765;
function myFunction() {
if (window.pageYOffset > yOffset) {
floating1.classList.add("sticky");
} else {
floating1.classList.remove("sticky");
}
}
table {
width: 100%;
min-height: 2000px;
}
table tr td {
vertical-align: top;
}
.sticky {
position: fixed!important;
top: 87px;
}
<table>
<tr>
<td style="background: red; width: 200px;">
...
</td>
<td style="background: green; width: 200px;">
<div id="floating1">
Floating content
</div>
</td>
</tr>
</table>
<div style="height: 1500px; background: blue;">
...
</div>
Use position: sticky that makes the element fixed in place until it encounters the edge of it's container:
window.onscroll = function() {
myFunction()
};
var floating1 = document.getElementById("floating1");
var yOffset = 765;
function myFunction() {
if (window.pageYOffset > yOffset) {
floating1.classList.add("sticky");
} else {
floating1.classList.remove("sticky");
}
}
table {
width: 100%;
min-height: 2000px;
}
table tr td {
vertical-align: top;
}
.sticky {
position: sticky;
top: 87px;
}
<table>
<tr>
<td style="background: red; width: 200px;">
...
</td>
<td style="background: green; width: 200px;">
<div id="floating1">
Floating content
</div>
</td>
</tr>
</table>
<div style="height: 1500px; background: blue;">
...
</div>
Here is a working fiddle: https://jsfiddle.net/17rn4qtw/2/.
I added id="parent" to the parent of the floating content and used Javascript to get its height.
I addded a second if clause in the function that only fixes the floating content if the page offset if less than the div content height.
I also subtracted the top pixels from the height of the parent so the floating content disappeared a when outside of the parent, not just when the parent was outside of the window view.
add a class green to your div and check when it reaches an end.
window.onscroll = function() {myFunction()};
var floating1 = document.getElementById("floating1");
var yOffset = 765;
function myFunction() {
if (window.pageYOffset > yOffset && window.pageYOffset < $('.green').height()) {
floating1.classList.add("sticky");
} else if (window.pageYOffset > $('.green').height()) {
floating1.classList.remove("sticky");
} else {
floating1.classList.remove("sticky");
}
}
table {
width: 100%;
min-height: 2000px;
}
table tr td {
vertical-align: top;
}
.sticky {
position: fixed!important;
top: 87px;
}
<table>
<tr>
<td style="background: red; width: 200px;">
...
</td>
<td style="background: green; width: 200px;" class="green">
<div id="floating1">
Floating content
</div>
</td>
</tr>
</table>
<div style="height: 1500px; background: blue;">
...
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
https://jsfiddle.net/djkog8ft/
i am working on my game but i have some problems...
1. if the image is in the class .room it has a another src but if you drop it in the class .items it should change to a icon. And if you drag it again to .room it will turn back.
2. There are many different image so i want to have a switch. if the draged objekt is dragging to .items the image should change. so the id of the image should go to the switch and check if the id and case is the same. the scr should be from the icon.
3. if it is possible i want to safe the id of the image in local.storage so i can use the objekt in the next page
<html>
<head>
<style>
.room {
width: 500px;
height: 150px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
.items {
width: 500px;
height: 150px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
</style>
<script>
function allowDrop(ev) {
if (ev.target.className === "items") {
ev.target.style.border = "3px dashed black";
}
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("img", ev.target.id);
}
function dragleave(ev) {
if (ev.target.className === "items") {
ev.target.style.border = "0px dashed transparent";
}
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("img");
ev.target.style.border = "0px dashed transparent";
if (ev.target=="[object HTMLImageElement]"){
ev.target = ev.target.parentNode;
}
else {
ev.target.appendChild(document.getElementById(data));
}
if (ev.target.id === ev.dataTransfer.getData("ori")) {
return;
}
var image = document.createElement("img");
image.id =
image.draggable = true;
image.addEventListener('dragstart', drag);
if (ev.target.className === 'items') {
icon();
} else if (ev.target.className === 'room') {
room();
}
var originEle = document.getElementById(ev.dataTransfer.getData("ori"));
originEle.outerHTML = '';
delete originEle;
ev.target.appendChild(image);
}
function icon(){
switch(image.id) {
case "teddy": image.src="pic/Icons/teddy.png";break;
case "book": image.src="pic/Icons/Buch.png";break;
}
}
function room(){
switch(image.id) {
case "teddy": image.src= "pic/Home/HomeRoom_booksL.png";break;
case "booksR": image.src= "pic/Home/HomeRoom_buch.png";break;}
}
function reset(){
var container = document.getElementById("field");
container.innerHTML= html;
}
var html;
window.onload = function(){
html = document.getElementById('field').innerHTML;
};
</script>
</head>
<body>
<h2>Drag and Drop</h2>
<div>
<div class="room" ondrop="drop(event)" ondragover="allowDrop(event)">
</div>
<h2>items</h2>
<div class="items" ondrop="drop(event)" ondragover="allowDrop(event)">
<img id="book" src="pic/Icons/Buch.png" draggable="true" ondragstart="drag(event)" id="drag1">
<img id="teddy" alt="booksL"src="pic/Home/HomeRoom_teddy.png" id="drag2" draggable="true" ondragstart="drag(event)" >
</div>
</div>
</body>
</html>
About the 3rd question - saving to localStorage:
add the code below to your drop function.
localStorage.setItem("name", data);
I have some code which tries to display temporary images from tempimages[] to img src with id=slide of box002, according to the random number selected from arrayVariable to ptag[i].
I want to display tempimages[0] first on img src of class box002, after dropping that image it gets deleted by the function Drop(ev), after that tempimages[i] should display img src of box002 for dropping likewise.
How to display images from an image array tempimages to class box img src?
I have used the function displayAllImages() to allocate images to img src id=slide, but it failed to display images.
box002 can be dragged and dropped to any box.
I want to display each image one by one from tempimages[] to img src of the box after each drop. How to change the code to achieve this property?
var tempimages = [];
function rvalue() {
var array = [];
var arrayVariable = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
var ArrayOfImages = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '6.jpg', '7.jpg', '8.jpg', '9.jpg', '10.jpg'];
arrayLength = arrayVariable.length;
ptags = document.getElementsByName("values");
for (i = 0; i < ptags.length; i++) {
ptags[i].innerHTML = arrayVariable[Math.floor(Math.random() * arrayLength)];
array.push(ptags[i].textContent);
tempimages.push(`${ptags[i].textContent}.jpg`); // want to display array to box002 to imgtag
}
}
function displayAllImages() {
var
i = 0,
len = tempimages.length;
for (; i < tempimages.length; i++) {
var img = new Image();
img.src = tempimages[i];
img.style.width = '100px';
img.style.height = '100px';
document.getElementById('slide').appendChild(img);
}
};
$(function() {
displayAllImages();
});
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");
var el = document.getElementById(data);
el.parentNode.removeChild; // deleting drag item
ev.target.style.backgroundColor = 'initial'; //[value indicate which box element] bgcoclor none
var pParagraph = ev.target.firstElementChild;
ev.target.removeChild(pParagraph);
alert(el);
}
#container {
margin-top:-2%;
white-space:nowrap;
text-align:center;
margin-left:20%;
margin-right:30%;
}
.box {
background-color: coral;
width: 60px;
height:60px;
margin-top:10px;
display:inline-block;
border-radius:5px;
border:2px solid #333;
border-color: #e6e600;
border-radius: 10%;
background-color: #ffcc00;
}
.box002 {
float: left;
width: 50px;
height: 50px;
float: left;
margin-left:30%;
padding-top:2%;
background-color:#ffff00 2px;
border:2px solid #000066;
}
.text {
padding: 20px;
margin:7 px;
margin-top:10px;
color:white;
font-weight:bold;
text-align:center;
}
#container {
white-space:nowrap;
text-align:center;
margin-left:20%;
margin-right:30%;
}
.text {
padding: 20px;
margin:7 px;
margin-top:10px;
color:white;
font-weight:bold;
text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body onload="rvalue()">
<div id="container">
<div class="box" ondrop="drop(event)" ondragover="allowDrop(event)" id="10">
<p name="values"></p>
</div>
<div class="box" ondrop="drop(event)" ondragover="allowDrop(event)" id="11">
<p name="values"></p>
</div>
<div class="box" ondrop="drop(event)" ondragover="allowDrop(event)" id="12">
<p name="values"></p>
</div>
</div>
<div class="box002" draggable="true" ondragstart="drag(event)" id="2">
<img src="" draggable="true" id="slide" style="width:30px; height:30px; border-radius: 50%;" border="rounded"/>
</div>
</body>
I'm not a 100% sure what it is you're trying achieve but here is something which might get you to the where you want to get. It picks three items at random and updates the image in the slide element after each time the slide is dropped on one of the boxes.
I've made a couple of changes, see the comments in the code as to why I've made the changes. When I saw this code first I didn't understand the need for two separate arrays so I've merged them into a single array.
var tempimages = [];
function rvalue() {
const
items = [
{ label: '1', url: 'https://via.placeholder.com/75x75?text=1' },
{ label: '2', url: 'https://via.placeholder.com/75x75?text=2' },
{ label: '3', url: 'https://via.placeholder.com/75x75?text=3' },
{ label: '4', url: 'https://via.placeholder.com/75x75?text=4' },
{ label: '5', url: 'https://via.placeholder.com/75x75?text=5' },
{ label: '6', url: 'https://via.placeholder.com/75x75?text=6' },
{ label: '7', url: 'https://via.placeholder.com/75x75?text=7' },
{ label: '8', url: 'https://via.placeholder.com/75x75?text=8' },
{ label: '9', url: 'https://via.placeholder.com/75x75?text=9' },
{ label: '10', url: 'https://via.placeholder.com/75x75?text=10' }
],
ptags = Array.from(document.querySelectorAll('[name="values"]'));
ptags.forEach(ptag => {
const
// Generate a random index.
randomIndex = Math.floor(Math.random() * items.length),
// Get the at item from the random index (it is possible the same item
// gets picked multiple times as there is no check for duplicates).
item = items[randomIndex];
// Update the label
ptag.textContent = item.label;
// Push the item into the array.
tempimages.push(item);
});
}
function displayAllImages() {
// Check if there are still images in the array, if not exit.
if (tempimages.length === 0) {
return;
}
const
// Remove the item at index 0 from the array.
item = tempimages.shift(),
// Get the image element.
image = document.getElementById('slide');
// Update src attribute so it points to the new URL.
image.src = item.url;
};
$(function() {
// On start, do rvalue first. This is taken from the onload in the body
// as that fired later than this method which meant displayAllImages was
// called before rvalue.
rvalue();
displayAllImages();
});
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");
var el = document.getElementById(data);
el.parentNode.removeChild; // deleting drag item
// ev.currentTarget is a div with class box whereas target can
// be either the div or the p element. Using currentTarget ensures
// you know which element you're working with.
ev.currentTarget.style.backgroundColor = 'initial'; //[value indicate which box element] bgcoclor none
var pParagraph = ev.currentTarget.firstElementChild;
ev.currentTarget.removeChild(pParagraph);
// Show the next image in the slider..
displayAllImages();
}
#container {
margin-top:-2%;
white-space:nowrap;
text-align:center;
margin-left:20%;
margin-right:30%;
}
.box {
background-color: coral;
width: 60px;
height:60px;
margin-top:10px;
display:inline-block;
border-radius:5px;
border:2px solid #333;
border-color: #e6e600;
border-radius: 10%;
background-color: #ffcc00;
}
.box002 {
float: left;
width: 50px;
height: 50px;
float: left;
margin-left:30%;
padding-top:2%;
background-color:#ffff00 2px;
border:2px solid #000066;
}
.text {
padding: 20px;
margin:7 px;
margin-top:10px;
color:white;
font-weight:bold;
text-align:center;
}
#container {
white-space:nowrap;
text-align:center;
margin-left:20%;
margin-right:30%;
}
.text {
padding: 20px;
margin:7 px;
margin-top:10px;
color:white;
font-weight:bold;
text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="container">
<div class="box" ondrop="drop(event)" ondragover="allowDrop(event)" id="10">
<p name="values"></p>
</div>
<div class="box" ondrop="drop(event)" ondragover="allowDrop(event)" id="11">
<p name="values"></p>
</div>
<div class="box" ondrop="drop(event)" ondragover="allowDrop(event)" id="12">
<p name="values"></p>
</div>
</div>
<div class="box002" draggable="true" ondragstart="drag(event)" id="2">
<img src="" draggable="true" id="slide" style="width:30px; height:30px; border-radius: 50%;" border="rounded"/>
</div>
</body>
How can make a draggable element to remain displayed on its source box after being dragged?
Below the script to illustrate it:
function dragStart(ev) {
ev.dataTransfer.setData('text1', ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData('text1');
ev.target.appendChild(document.getElementById(data));
}
function allowDrop(ev) {
ev.preventDefault();
}
.boxarticle {
width: 200px;
height: 150px;
border: 1px solid blue;
margin: 0 0 10px 20
}
div#panier {
width: 150px;
height: 150px;
background-color: ;
border: 1px solid blue;
}
<!-- I want that image to remain here after I dragged it -->
<div class='boxarticle'>
<img src="https://cdn-images-1.medium.com/max/1200/1*QQvzwKk7rdC1JkY0XiPVUQ.png" draggable="true" id='image' data-price='9200' ondragstart="dragStart(event)" width=80 height=80>
</div>
<!-- where draggable element go in -->
<div id="panier" ondrop='drop(event)' ondragover="allowDrop(event)"> Drag and drop image here..but leave it in the source place </div>
You need to clone it and give it a new id, otherwise it will assume "drag".
HTML5 drag and copy?
function dragStart(ev)
{
ev.dataTransfer.setData('text1',ev.target.id);
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("text1");
var nodeCopy = document.getElementById(data).cloneNode(true);
nodeCopy.id = "randomId";
ev.target.appendChild(nodeCopy);
}
function allowDrop(ev)
{
ev.preventDefault();
}
.boxarticle {
width:200px;height: 150px; border:1px solid blue;margin: 0 0 10px 20
}
div#panier {
width:150px;height: 150px;background-color: ; border: 1px solid blue;
}
<!-- I want that image to remain here after I dragged it -->
<div class='boxarticle'>
<img src="https://cdn-images-1.medium.com/max/1200/1*QQvzwKk7rdC1JkY0XiPVUQ.png" draggable="true" id='image' data-price='9200' ondragstart="dragStart(event)" width=80 height=80>
</div>
<!-- where draggable element go in -->
<div id="panier" ondrop='drop(event)' ondragover="allowDrop(event)"> Drag and drop image here..but leave it in the source place </div>
I have the following working code (also see this fiddle):
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1 {width:350px;height:170px;padding:10px;border:1px solid #aaaaaa;}
#drag1 {width:50px;height:50px;padding:10px;border:1px solid #000;background-color: #f00; position: absolute;}
</style>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text/html", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text/html");
ev.target.appendChild(document.getElementById(data));
//window.alert( ev.clientX + ',' + ev.clientY);
document.getElementById("drag1").style.left = ev.clientX + 'px';
document.getElementById("drag1").style.top = ev.clientY + 'px';
return false;
}
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<div id="drag1" draggable="true" ondragstart="drag(event)"></div>
</div>
</body>
</html>
Here you can drag and drop a colored div only inside the main div. The problem is that this red div jumps a bit from his dropped position. I think this is because I use the mouse ev.clientX and Y. So how can I fix this so the DIV stays at the dropped position?
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text/html", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text/html");
ev.target.appendChild(document.getElementById(data));
//window.alert( ev.clientX + ',' + ev.clientY);
document.getElementById("drag1").style.left = ev.clientX + 'px';
document.getElementById("drag1").style.top = ev.clientY + 'px';
return false;
}
#div1 {width:350px;height:170px;padding:10px;border:1px solid #aaaaaa;}
#drag1 {width:50px;height:50px;padding:10px;border:1px solid #000;background-color: #f00; position: absolute;}
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<div id="drag1" draggable="true" ondragstart="drag(event)"></div>
</div>
You're dropping the div's top left corner to the mouse's location, you have to find the offset from inside the div where the mouse is actually dragging. By checking the event object(in chrome), offsetX and offsetY and layerX and layerY seem to have the offset from the origin of the div to the mouse.
Here is a question with alot of discussion on offsetXY and layerXY and associated properties event.offsetX in Firefox, note: don't just read the accepted answer.
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("application/json",
JSON.stringify([ev.target.id,
(ev.offsetX || ev.clientX - $(ev.target).offset().left),
(ev.offsetY || ev.clientY - $(ev.target).offset().top)]
));
}
function drop(ev) {
ev.preventDefault();
var data = JSON.parse(ev.dataTransfer.getData("application/json"));
ev.target.appendChild(document.getElementById(data[0]));
//window.alert( ev.clientX + ',' + ev.clientY);
document.getElementById("drag1")
.style.left = ev.clientX - data[1] + 'px';
document.getElementById("drag1").style.top = ev.clientY - data[2] + 'px';
return false;
}
#div1 { width:350px; height:170px; padding:10px; border:1px solid #aaaaaa; }
#drag1 { width:50px; height:50px; padding:10px; border:1px solid #000; background-color: #f00; position: absolute; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<div id="drag1" draggable="true" ondragstart="drag(event)"></div>
</div>