Swap (Drag Drop) not working in a specific div - javascript

I am working on sort of a puzzle game which looks something like in the below mentioned images
When I Swap content (Drag and Drop) just on the elements of mainDiv1, it is working fine.
[Swapping within mainDiv1]
It also works in the way when I Drag and Drop the elements (images) from mainDiv1 to mainDiv2.
[mainDiv1 to mainDiv2 image drag and drop on different divs]
PROBLEM:
1. When I try to swap the elements in mainDiv2, it is not working. The element being dragged just disappears.
2. If I try to put these images back to the mainDiv1, I cannot do that too.
Can anyone please tell me where I am going wrong or if it is possible to call multiple functions on ondrag / ondrop.
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("src", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var src = document.getElementById(ev.dataTransfer.getData("src"));
var srcParent = src.parentNode;
var tgt = ev.currentTarget.firstElementChild;
ev.currentTarget.replaceChild(src, tgt);
srcParent.appendChild(tgt);
}
function drop1(ev){
ev.preventDefault();
var data = ev.dataTransfer.getData("src");
ev.target.appendChild(document.getElementById(data));
}
#maindiv1
{
width: 48%;
height: fit-content;
background-color: #ffc7b1;
border: 1px solid;
float: left;
}
#div1
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: red;
}
#div2
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: orange;
}
#div3
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: yellow;
}
#div4
{
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: green;
}
#div5
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: blue;
}
#div6
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: violet;
}
#div7
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: indigo;
}
#div8
{
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: chocolate;
}
#div9
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: teal;
}
#div10
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: darkolivegreen;
}
#div11
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: salmon;
}
#div12
{
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: plum;
}
#img1
{
width: 100%;
height: 200px;
}
#img2
{
width: 100%;
height: 200px;
}
#img3
{
width: 100%;
height: 200px;
}
#img4
{
width: 100%;
height: 200px;
}
#img5
{
width: 100%;
height: 200px;
}
#img6
{
width: 100%;
height: 200px;
}
#img7
{
width: 100%;
height: 200px;
}
#img8
{
width: 100%;
height: 200px;
}
#img9
{
width: 100%;
height: 200px;
}
#img10
{
width: 100%;
height: 200px;
}
#img11
{
width: 100%;
height: 200px;
}
#img12
{
width: 100%;
height: 200px;
}
#separator
{
width: 2%;
height: 500px;
background-color: white;
float: left;
}
#maindiv2
{
width: 48%;
height: fit-content;
background-color: #ffc7b1;
border: 1px solid;
float: left;
}
#odiv1
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: red;
}
#odiv2
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: orange;
}
#odiv3
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: yellow;
}
#odiv4
{
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: green;
}
#odiv5
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: blue;
}
#odiv6
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: violet;
}
#odiv7
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: indigo;
}
#odiv8
{
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: chocolate;
}
#odiv9
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: teal;
}
#odiv10
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: darkolivegreen;
}
#odiv11
{
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: salmon;
}
#odiv12
{
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: plum;
}
<div id="maindiv1">
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/1.gif" alt="Image not available" id="img1" ondragstart="drag(event)" draggable="true">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/2.gif" alt="Image not available" id="img2" ondragstart="drag(event)" draggable="true">
</div>
<div id="div3" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/3.gif" alt="Image not available" id="img3" ondragstart="drag(event)" draggable="true">
</div>
<div id="div4" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/4.gif" alt="Image not available" id="img4" ondragstart="drag(event)" draggable="true">
</div>
<div id="div5" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/5.gif" alt="Image not available" id="img5" ondragstart="drag(event)" draggable="true">
</div>
<div id="div6" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/6.gif" alt="Image not available" id="img6" ondragstart="drag(event)" draggable="true">
</div>
<div id="div7" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/7.gif" alt="Image not available" id="img7" ondragstart="drag(event)" draggable="true">
</div>
<div id="div8" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/8.gif" alt="Image not available" id="img8" ondragstart="drag(event)" draggable="true">
</div>
<div id="div9" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/9.gif" alt="Image not available" id="img9" ondragstart="drag(event)" draggable="true">
</div>
<div id="div10" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/10.gif" alt="Image not available" id="img10" ondragstart="drag(event)" draggable="true">
</div>
<div id="div11" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/11.gif" alt="Image not available" id="img11" ondragstart="drag(event)" draggable="true">
</div>
<div id="div12" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/12.gif" alt="Image not available" id="img12" ondragstart="drag(event)" draggable="true">
</div>
</div>
<div id="separator"></div>
<div id="maindiv2">
<div id="odiv1" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
<div id="odiv2" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
<div id="odiv3" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
<div id="odiv4" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
<div id="odiv5" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
<div id="odiv6" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
<div id="odiv7" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
<div id="odiv8" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
<div id="odiv9" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
<div id="odiv10" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
<div id="odiv11" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
<div id="odiv12" ondrop="drop1(event)" ondragover="allowDrop(event)">
</div>
</div>

tl;dr:
Merge drop and drop1 functions into one which handles both cases and apply it to all divs:
function drop(ev) {
ev.preventDefault();
var src = document.getElementById(ev.dataTransfer.getData("src"));
if (src) {
var tgt = ev.currentTarget.firstElementChild;
if (tgt) {
var srcParent = src.parentNode;
ev.currentTarget.replaceChild(src, tgt);
srcParent.appendChild(tgt);
} else {
ev.currentTarget.appendChild(src);
}
}
}
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("src", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var src = document.getElementById(ev.dataTransfer.getData("src"));
if (src) {
var tgt = ev.currentTarget.firstElementChild;
if (tgt) {
var srcParent = src.parentNode;
ev.currentTarget.replaceChild(src, tgt);
srcParent.appendChild(tgt);
} else {
ev.currentTarget.appendChild(src);
}
}
}
#maindiv1 {
width: 48%;
height: fit-content;
background-color: #ffc7b1;
border: 1px solid;
float: left;
}
#div1 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: red;
}
#div2 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: orange;
}
#div3 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: yellow;
}
#div4 {
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: green;
}
#div5 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: blue;
}
#div6 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: violet;
}
#div7 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: indigo;
}
#div8 {
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: chocolate;
}
#div9 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: teal;
}
#div10 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: darkolivegreen;
}
#div11 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: salmon;
}
#div12 {
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: plum;
}
#img1 {
width: 100%;
height: 200px;
}
#img2 {
width: 100%;
height: 200px;
}
#img3 {
width: 100%;
height: 200px;
}
#img4 {
width: 100%;
height: 200px;
}
#img5 {
width: 100%;
height: 200px;
}
#img6 {
width: 100%;
height: 200px;
}
#img7 {
width: 100%;
height: 200px;
}
#img8 {
width: 100%;
height: 200px;
}
#img9 {
width: 100%;
height: 200px;
}
#img10 {
width: 100%;
height: 200px;
}
#img11 {
width: 100%;
height: 200px;
}
#img12 {
width: 100%;
height: 200px;
}
#separator {
width: 2%;
height: 500px;
background-color: white;
float: left;
}
#maindiv2 {
width: 48%;
height: fit-content;
background-color: #ffc7b1;
border: 1px solid;
float: left;
}
#odiv1 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: red;
}
#odiv2 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: orange;
}
#odiv3 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: yellow;
}
#odiv4 {
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: green;
}
#odiv5 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: blue;
}
#odiv6 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: violet;
}
#odiv7 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: indigo;
}
#odiv8 {
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: chocolate;
}
#odiv9 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: teal;
}
#odiv10 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: darkolivegreen;
}
#odiv11 {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
background-color: salmon;
}
#odiv12 {
border: 1px solid;
width: 24.2%;
height: 200px;
float: left;
background-color: plum;
}
<div id="maindiv1">
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/1.gif" alt="Image not available" id="img1" ondragstart="drag(event)" draggable="true"></div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/2.gif" alt="Image not available" id="img2" ondragstart="drag(event)" draggable="true"></div>
<div id="div3" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/3.gif" alt="Image not available" id="img3" ondragstart="drag(event)" draggable="true"></div>
<div id="div4" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/4.gif" alt="Image not available" id="img4" ondragstart="drag(event)" draggable="true"></div>
<div id="div5" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/5.gif" alt="Image not available" id="img5" ondragstart="drag(event)" draggable="true"></div>
<div id="div6" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/6.gif" alt="Image not available" id="img6" ondragstart="drag(event)" draggable="true"></div>
<div id="div7" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/7.gif" alt="Image not available" id="img7" ondragstart="drag(event)" draggable="true"></div>
<div id="div8" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/8.gif" alt="Image not available" id="img8" ondragstart="drag(event)" draggable="true"></div>
<div id="div9" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/9.gif" alt="Image not available" id="img9" ondragstart="drag(event)" draggable="true"></div>
<div id="div10" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/10.gif" alt="Image not available" id="img10" ondragstart="drag(event)" draggable="true"></div>
<div id="div11" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/11.gif" alt="Image not available" id="img11" ondragstart="drag(event)" draggable="true"></div>
<div id="div12" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="images/12.gif" alt="Image not available" id="img12" ondragstart="drag(event)" draggable="true"></div>
</div>
<div id="separator"></div>
<div id="maindiv2">
<div id="odiv1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="odiv2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="odiv3" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="odiv4" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="odiv5" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="odiv6" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="odiv7" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="odiv8" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="odiv9" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="odiv10" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="odiv11" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="odiv12" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</div>
proper answer:
Whenever you find yourself writing the same line of code twice, you should try to find a way to only write it once.
Taking the CSS, for example, instead of writing each property for each child, using that child as a selector, you should consider writing it only once, using the parent as selector:
#maindiv1, #maindiv2 {
width: 48%;
height: fit-content;
background-color: #ffc7b1;
border: 1px solid;
float: left;
}
#maindiv1 > div, #maindiv2 > div {
border: 1px solid;
width: 24.9%;
height: 200px;
float: left;
}
#maindiv1 > div img {
width: 100%;
height: 200px;
}
#separator {
width: 2%;
height: 500px;
background-color: white;
float: left;
}
#div1, #odiv1 { background-color: red; }
#div2, #odiv2 { background-color: orange; }
#div3, #odiv3 { background-color: yellow; }
#div4, #odiv4 { background-color: green; }
#div5, #odiv5 { background-color: blue; }
#div6, #odiv6 { background-color: violet; }
#div7, #odiv7 { background-color: indigo; }
#div8, #odiv8 { background-color: chocolate; }
#div9, #odiv9 { background-color: teal; }
#div10, #odiv10 { background-color: darkolivegreen; }
#div11, #odiv11 { background-color: salmon; }
#div12, #odiv12 { background-color: plum; }
The advantage being that, when you decide to make a change, you only change in one place and they all change. Like, for example, removing the hard-coded 200px height and making them responsive.
The exact same principle applies to JavaScript. Rather than specifying the same function for the same event for each element, you should use a function/routine which goes through each of them and applies it:
const leftDivs = document.querySelector('#maindiv1').querySelectorAll('div');
[...leftDivs].forEach(div => {
div.ondrop = drop;
div.ondragover = allowDrop;
});
const rightDivs = document.querySelector('#maindiv2').querySelectorAll('div');
[...rightDivs].forEach(div => {
// `drop`, not `drop1`! We'll merge the two functions into one in next step
div.ondrop = drop;
div.ondragover = allowDrop;
});
const images = document.querySelector('#maindiv1').querySelectorAll('img');
[...images].forEach(img => {
img.ondragstart = drag;
img.draggable = true;
})
Obviously, you now need to remove the hardcoded ondrop, ondragover, ondragstart and draggable attributes, since you're applying them dynamically. Also note in the final working example (which you'll find at the end of the answer) I opted to rename all those functions to the exact attribute name they are being assigned to. It's clearer, hence easier to follow.
But, to have this working, instead of having two different functions handling each case:
when you drop inside an element which already has an image
when you drop inside an empty one
we should merge both into only one function:
function drop(ev) {
ev.preventDefault();
var src = document.getElementById(ev.dataTransfer.getData("src"));
var srcParent = src.parentNode;
var tgt = ev.currentTarget.firstElementChild;
if (tgt) {
ev.currentTarget.replaceChild(src, tgt);
srcParent.appendChild(tgt);
} else {
// if no `tgt`, (currentTarget is empty), just place the image (src) into it
ev.currentTarget.appendChild(src);
}
}
Speaking of which, I find your naming conventions a bit confusing. One might think naming is not important but, in the long run, good naming conventions greatly reduce the time needed to understand (and modify) the code. Here's how I'd have written that function:
function ondrop(ev) {
ev.preventDefault();
const image = document.getElementById(ev.dataTransfer.getData("src"));
// only proceed if `image` exists
if (image) {
const targetImage = ev.currentTarget.firstElementChild;
if (targetImage) {
// define `imageParent` only for the case where it is used
const imageParent = image.parentNode;
ev.currentTarget.replaceChild(image, targetImage);
imageParent.appendChild(targetImage);
} else {
ev.currentTarget.appendChild(image);
}
}
}
Let's see it working.
I took the liberty to clean it up more, I renamed a few things and also changed the CSS to have some basic responsiveness - it's not perfect but, IMHO, it's better:
const leftDivs = document.querySelector('#maindiv1').querySelectorAll('div');
const rightDivs = document.querySelector('#maindiv2').querySelectorAll('div');
[...leftDivs].concat([...rightDivs]).forEach(div => {
div.ondrop = ondrop;
div.ondragover = ondragover;
});
const images = document.querySelector('#maindiv1').querySelectorAll('img');
[...images].forEach(img => {
img.ondragstart = ondragstart;
img.draggable = true;
})
function ondragover(e) {
e.preventDefault();
}
function ondragstart(e) {
e.dataTransfer.setData("imageId", e.currentTarget.id);
}
function ondrop(e) {
e.preventDefault();
const img = document.getElementById(e.dataTransfer.getData("imageId"));
if (img) {
const targetImg = e.currentTarget.firstElementChild;
if (targetImg) {
const imgParent = img.parentNode;
e.currentTarget.replaceChild(img, targetImg);
imgParent.appendChild(targetImg);
} else {
e.currentTarget.appendChild(img);
}
}
}
* {
/* make all elements include border in width, so you don't have to use 24.9% */
box-sizing: border-box;
}
#maindiv1,
#maindiv2 {
width: 48%;
height: fit-content;
background-color: #ffc7b1;
float: left;
}
#maindiv1>div,
#maindiv2>div {
width: 25%;
padding-bottom: 25%;
float: left;
position: relative;
}
#maindiv1>div img,
#maindiv2>div img {
display: block;
width: 100%;
height: auto;
position: absolute;
}
#separator {
width: 2%;
min-height: 10px;
background-color: white;
float: left;
}
#div1,
#odiv1 {
background-color: red;
}
#div2,
#odiv2 {
background-color: orange;
}
#div3,
#odiv3 {
background-color: yellow;
}
#div4,
#odiv4 {
background-color: green;
}
#div5,
#odiv5 {
background-color: blue;
}
#div6,
#odiv6 {
background-color: violet;
}
#div7,
#odiv7 {
background-color: indigo;
}
#div8,
#odiv8 {
background-color: chocolate;
}
#div9,
#odiv9 {
background-color: teal;
}
#div10,
#odiv10 {
background-color: darkolivegreen;
}
#div11,
#odiv11 {
background-color: salmon;
}
#div12,
#odiv12 {
background-color: plum;
}
<div id="maindiv1">
<div id="div1">
<img src="https://picsum.photos/id/237/200/200" alt="" id="img1">
</div>
<div id="div2">
<img src="https://picsum.photos/id/238/200/200" alt="" id="img2">
</div>
<div id="div3">
<img src="https://picsum.photos/id/239/200/200" alt="" id="img3">
</div>
<div id="div4">
<img src="https://picsum.photos/id/240/200/200" alt="" id="img4">
</div>
<div id="div5">
<img src="https://picsum.photos/id/241/200/200" alt="" id="img5">
</div>
<div id="div6">
<img src="https://picsum.photos/id/242/200/200" alt="" id="img6">
</div>
<div id="div7">
<img src="https://picsum.photos/id/243/200/200" alt="" id="img7">
</div>
<div id="div8">
<img src="https://picsum.photos/id/244/200/200" alt="" id="img8">
</div>
<div id="div9">
<img src="https://picsum.photos/id/247/200/200" alt="" id="img9">
</div>
<div id="div10">
<img src="https://picsum.photos/id/248/200/200" alt="" id="img10">
</div>
<div id="div11">
<img src="https://picsum.photos/id/249/200/200" alt="" id="img11">
</div>
<div id="div12">
<img src="https://picsum.photos/id/250/200/200" alt="" id="img12">
</div>
</div>
<div id="separator"></div>
<div id="maindiv2">
<div id="odiv1"></div>
<div id="odiv2"></div>
<div id="odiv3"></div>
<div id="odiv4"></div>
<div id="odiv5"></div>
<div id="odiv6"></div>
<div id="odiv7"></div>
<div id="odiv8"></div>
<div id="odiv9"></div>
<div id="odiv10"></div>
<div id="odiv11"></div>
<div id="odiv12"></div>
</div>

Related

How to show 6 different images every time the website is loaded?

I'm having a div which contains 10 images, when any one visit or reload the page any of the 6 images should be displayed in a random arrangement. Finally I come with random arrangements but I can't control the number of images and also the images are going out of the div. Is there any way to show 6 different images when in load the website every time
$(".image-box").html($(".image-box").children().sort(function() { return 0.5 - Math.random() }));
});
.image-box {
height: 100%;
border: 1px solid #e5e5e5;
border-radius: 8px;
margin-top: 10px;
white-space: nowrap;
overflow: auto;
}
.image-box-title {
padding: 10px;
width: 2200px;
border-bottom: 1px solid #e5e5e5;
border-top: 0p;
border-right: 0px;
border-left: 0px;
border-radius: 8px 8px 0px 0px;
background-color: #583d72;
color: #ff8e71;
}
.tester {
display: inline-block;
width: 212px;
height: 200px;
margin: 5px 0 0 5px;
}
#a {
background-color: black;
}
#b {
background-color: yellow;
}
#c {
background-color: red;
}
#d {
background-color: green;
}
#e {
background-color: pink;
}
#f {
background-color: skyblue;
}
#g {
background-color: orange;
}
#h {
background-color: grey;
}
#i {
background-color: darkgreen;
}
#j {
background-color: darkblue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="image-box" id="images">
<div class="image-box-title">Images</div>
<div id="a" class="tester"></div>
<div id="b" class="tester"></div>
<div id="c" class="tester"></div>
<div id="d" class="tester"></div>
<div id="e" class="tester"></div>
<div id="f" class="tester"></div>
<div id="g" class="tester"></div>
<div id="h" class="tester"></div>
<div id="i" class="tester"></div>
<div id="j" class="tester"></div>
</div>
You could define with CSS that all images are hidden with display: none and only the first 6 images are visible (first child is the title):
.tester:nth-child(2),
.tester:nth-child(3),
.tester:nth-child(4),
.tester:nth-child(5),
.tester:nth-child(6),
.tester:nth-child(7) {
display: inline-block;
}
Furthermore your title has a width of 2200px which seems to be unnecessary because it has display: block defined. Therefor you could omit the width (that was the reason for the images going out of the div).
Because the title is also a child of the image box it is also shuffled. Therefor you should make it the first child after shuffling:
$(".image-box").prepend($(".image-box-title").detach());
Working example:
$(".image-box").html($(".image-box").children().sort(function() {
return 0.5 - Math.random()
}));
$(".image-box").prepend($(".image-box-title").detach());
.image-box {
height: 100%;
border: 1px solid #e5e5e5;
border-radius: 8px;
margin-top: 10px;
white-space: nowrap;
overflow: auto;
}
.image-box-title {
padding: 10px;
/*width: 2200px; not necessary? */
border-bottom: 1px solid #e5e5e5;
border-top: 0p;
border-right: 0px;
border-left: 0px;
border-radius: 8px 8px 0px 0px;
background-color: #583d72;
color: #ff8e71;
}
.tester {
display: none;
width: 212px;
height: 200px;
margin: 5px 0 0 5px;
}
#a {
background-color: black;
}
#b {
background-color: yellow;
}
#c {
background-color: red;
}
#d {
background-color: green;
}
#e {
background-color: pink;
}
#f {
background-color: skyblue;
}
#g {
background-color: orange;
}
#h {
background-color: grey;
}
#i {
background-color: darkgreen;
}
#j {
background-color: darkblue;
}
.tester:nth-child(2),
.tester:nth-child(3),
.tester:nth-child(4),
.tester:nth-child(5),
.tester:nth-child(6),
.tester:nth-child(7) {
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="image-box" id="images">
<div class="image-box-title">Images</div>
<div id="a" class="tester"></div>
<div id="b" class="tester"></div>
<div id="c" class="tester"></div>
<div id="d" class="tester"></div>
<div id="e" class="tester"></div>
<div id="f" class="tester"></div>
<div id="g" class="tester"></div>
<div id="h" class="tester"></div>
<div id="i" class="tester"></div>
<div id="j" class="tester"></div>
</div>

Trigger Onclick on Child Layered Divs with Z-index, pointer-events doesn't work

I want to be able to click and change the color of the background(div) with cut out by png.
<body>
<div style="border: 1px solid red; width: 650px; height: 500px; margin: 0px auto; pointer-events: none; ;">
<div class="frame" style="background-color: blue; -webkit-mask-image: url('./assets/Layer1.png'); z-index: 0"></div>
<div class="frame" style="background-color: red; -webkit-mask-image: url('./assets/Layer2.png'); z-index: 1"></div>
<div class="frame" style="background-color: grey; -webkit-mask-image: url('./assets/Layer3.png'); z-index: 2"></div>
<div class="frame" style="background-color: yellow; -webkit-mask-image: url('./assets/Layer4.png'); z-index: 3"></div>
</div>
<style>
.frame {
position: absolute;
pointer-events: auto;
width: 640px;
height: 490px;
padding: 1px;
margin: 0px auto;
box-sizing: border-box;
}
</style>
</body>
IMAGE
Add an ID to the parent div, and a click handler on it.
let parent = document.getElementById('parent')
parent.addEventListener('click', function() {
parent.style.backgroundColor = event.target.style.backgroundColor;
})

conditions for divs in drag and drop

I have 2 droppable divs called drop1 and drop2, and 2 draggable elements called ans1 and ans2. I want to make an alert when ans1 is inside drop1 and ans2 is inside drop2. Both conditions have to be fulfilled (not caring about which is fulfilled first) in order for the alert to come out.
$("#ans1, #ans2").draggable({
revert: "valid",
cursor: "move"
});
$("#drop1, #drop2").droppable({
drop: function (event, ui) {
if ($("#ans1", $("#drop1")) && $("#ans2", $(".drop2"))) {
alert("correct");
}
});
<div id="drop1" class="b1" style="background-color: white; border: solid; height: 6vw; width: 13vw; border-radius: 7px">
</div>
<div id="drop2" class="b1" style="background-color: white; border: solid; height: 6vw; width: 13vw; border-radius: 7px">
</div>
<div id="ans2" style="background-color: white; border: solid; cursor: move; height: 6vw; width: 13vw; border-radius: 7px">
a change
</div>
<br/>
<div id="ans1" style="background-color: white; border: solid; cursor: move; height: 6vw; width: 13vw; border-radius: 7px">
chemical reaction system
</div>
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1, #div2 {
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));
}
</script>
</head>
<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)">
<img src="https://www.google.co.in/logos/doodles/2018/sergei-eisensteins-120th-birthday-5380775741489152.2-s.png" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</body>
</html>
Try to use accept option and ui.draggable.text() of the droppable() function
Stack Snippet
$(".drag-div>div").draggable({
revert: "invalid",
cursor: "move"
})
$(".drop-div>div").droppable({
accept: ".drag-div>div",
drop: function(event, ui) {
$(this).text(ui.draggable.text());
if ($("#drop1").text() == $("#ans1").text() && $("#drop2").text() == $("#ans2").text()) {
alert("correct");
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="drop-div">
<div id="drop1" class="b1" style="background-color: white; border: solid; height: 6vw; width: 13vw; border-radius: 7px">
</div>
<br/>
<div id="drop2" class="b1" style="background-color: white; border: solid; height: 6vw; width: 13vw; border-radius: 7px">
</div>
</div>
<br/>
<div class="drag-div">
<div id="ans2" style="background-color: white; border: solid; cursor: move; height: 6vw; width: 13vw; border-radius: 7px">
a change
</div>
<br/>
<div id="ans1" style="background-color: white; border: solid; cursor: move; height: 6vw; width: 13vw; border-radius: 7px">
chemical
</div>
</div>

Create an automatic slider

I created this code for a slider. When I hover the thumbnail image it shows me image, but I need to create an automatic slider. How can i do this?
/******************************************************************************************************/
.sliderconteainer {
width: 100%;
position: relative;
border: 2px double silver;
border-radius: 5px;
}
.thmbnail {
width: 25%;
height: 100px;
float: left;
}
.slide {
width: 100%;
height: 300px;
position: absolute;
float: right;
left: 0;
top: 0;
opacity: 0;
}
.slide img {
height: 300px;
width: 100%;
}
.thmbnail img {
width: 100%;
height: 95%;
border: 2px solid #EEEEEE;
border-radius: 5px;
}
.content-placeholder {
width: 100%;
height: 300px;
}
.info {
background-color: black;
z-index: 99;
margin-top: -66px;
position: absolute;
width: 100%;
padding-right: 10px;
opacity: .75;
border-radius: 5px;
}
.info p {
color: #ABB3BD;
font-family: 'B Mitra';
}
.info h5 {
font-family: 'B Titr';
color: #ffffff;
}
.thmbnail:hover .slide {
opacity: 1;
}
.thmbnail:hover .thmbnail img {
border: 2px solid #56656E;
}
#main {
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="main">
<div class=" sliderconteainer col-md-5 col-sm-5">
<div class="content-placeholder"></div>
<div class="thmbnail">
<div class="slide">
<img src="~/Image/SiteDesign/profile.jpg" class="img-responsive"/>
<div class="info">
<h5>عنوان برای اسلید اول</h5>
<p>توضیحالت اسلاید دوم</p>
</div>
</div>
<img src="~/Image/SiteDesign/profile.jpg"/>
</div>
<div class="thmbnail">
<div class="slide">
<img src="~/Image/Slider/8.jpg"/>
<div class="info">
<h5>عنوان برای اسلید اول</h5>
<p>توضیحالت اسلاید دوم</p>
</div>
</div>
<img src="~/Image/Slider/8.jpg"/>
</div>
<div class="thmbnail">
<div class="slide">
<img src="~/Image/Slider/image-slider-2.jpg"/>
<div class="info">
<h5>عنوان برای اسلید اول</h5>
<p>توضیحالت اسلاید دوم</p>
</div>
</div>
<img src="~/Image/Slider/image-slider-2.jpg"/>
</div>
<div class="thmbnail ">
<div class="slide">
<img src="~/Image/Slider/Megumi-4565.jpg"/>
<div class="info">
<h5>عنوان برای اسلید اول</h5>
<p>توضیحالت اسلاید دوم</p>
</div>
</div>
<img src="~/Image/Slider/Megumi-4565.jpg"/>
</div>
</div>
</div>
If you want to change things automatically, you can use the build-in JavaScript function setInterval(xfunction, xInterval), which calls xFunction, every xInterval
setInterval(function() {
console.log("MOVE IT");
moveLeft();
}, 1000);
As #dennis-koch mentioned, I would also have a look at plugins you may use for a slider.

Duplicating Image within Drag and Drop Grid

I have a drag and drop where you drag images from the sidebar into a grid. It clones the image when it goes into the grid. Although, when I drag an image in the grid to another grid space, it copies it, and I don't want it to. This is my 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");
var el = ev.target;
if (!el.classList.contains('dropzone')) {
el = ev.target.parentNode;
ev.target.remove();
}
el.appendChild(document.getElementById(data).cloneNode(true));
}
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
document.getElementsByTagName("body")[0].style.marginLeft = "250px";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
document.getElementsByTagName("body")[0].style.marginLeft= "0";
}
#div1, #div2, #div3, #div4{
float: left;
width: 55px;
height: 55px;
border: 1px solid black;
}
#div5, #div6, #div7, #div8{
float: left;
width: 55px;
height: 55px;
border: 1px solid black;
}
#div9, #div10, #div11, #div12{
float: left;
width: 55px;
height: 55px;
border: 1px solid black;
}
#div13, #div14, #div15, #div16{
float: left;
width: 55px;
height: 55px;
border: 1px solid black;
}
.row2 {
clear: both;
}
.row3 {
clear: both;
}
.row4 {
clear: both;
}
body {
transition: margin .5s;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s
}
.sidenav a:hover, .offcanvas a:focus{
color: #f1f1f1;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
#main {
transition: margin-left .5s;
padding: 16px;
}
.row {
width:100%;
display:inline-block;
margin-bottom:10px;
}
#media screen and (max-height: 450px) {
.sidenav {
padding-top: 15px;
}
.sidenav a {
font-size: 18px;
}
}
<!DOCTYPE html>
<html>
<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");
var el = ev.target;
if (!el.classList.contains('dropzone')) {
el = ev.target.parentNode;
ev.target.remove();
}
el.appendChild(document.getElementById(data).cloneNode(true));
}
function openNav() {
document.getElementById("mySidenav").style.width = "250px";
document.getElementsByTagName("body")[0].style.marginLeft = "250px";
}
function closeNav() {
document.getElementById("mySidenav").style.width = "0";
document.getElementsByTagName("body")[0].style.marginLeft= "0";
}
</script>
<body>
<div id="main">
<span style="font-size:30px;cursor:pointer" onclick="openNav()">☰ Materials</span>
</div>
<div id="div1" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div2" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div3" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div4" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="row2">
<div id="div5" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div6" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div7" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div8" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</div>
<div class="row3">
<div id="div9" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div10" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div11" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div12" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</div>
<div class="row4">
<div id="div13" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div14" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div15" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div id="div16" class="dropzone" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</div>
<div id="mySidenav" class="sidenav">
×
<a href="#">
<img src="bricks.jpg" draggable="true" ondragstart="drag(event)" id="drag1" width="55" height="55">
Bricks
</a>
<a href="#">
<img src="halfbrick.png" draggable="true" ondragstart="drag(event)" id="drag1.3" width="55" height="55">
Half Brick
</a>
<a href="#">
<img src="halfbrick2.png" draggable="true" ondragstart="drag(event)" id="drag1.6" width="55" height="55">
Half Brick
</a>
<a href="#">
<img src="#" draggable = "true" ondragstart="drag(event)" id="drag2" width="55" height="55">
Stone
</a>
<a href="#">
<img src="#" draggable = "true" ondragstart="drag(event)" id="drag3" width="55" height="55">
Wood
</a>
<a href="#">
<img src="#" draggable="true" ondragstart="drag(event)" id="drag4" width="55" height="55">
Eraser
</a>
</div>
</body>
<style>
#div1, #div2, #div3, #div4{
float: left;
width: 55px;
height: 55px;
border: 1px solid black;
}
#div5, #div6, #div7, #div8{
float: left;
width: 55px;
height: 55px;
border: 1px solid black;
}
#div9, #div10, #div11, #div12{
float: left;
width: 55px;
height: 55px;
border: 1px solid black;
}
#div13, #div14, #div15, #div16{
float: left;
width: 55px;
height: 55px;
border: 1px solid black;
}
.row2 {
clear: both;
}
.row3 {
clear: both;
}
.row4 {
clear: both;
}
body {
transition: margin .5s;
}
.sidenav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
transition: 0.5s;
padding-top: 60px;
}
.sidenav a {
padding: 8px 8px 8px 32px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
transition: 0.3s
}
.sidenav a:hover, .offcanvas a:focus{
color: #f1f1f1;
}
.sidenav .closebtn {
position: absolute;
top: 0;
right: 25px;
font-size: 36px;
margin-left: 50px;
}
#main {
transition: margin-left .5s;
padding: 16px;
}
.row {
width:100%;
display:inline-block;
margin-bottom:10px;
}
#media screen and (max-height: 450px) {
.sidenav {
padding-top: 15px;
}
.sidenav a {
font-size: 18px;
}
}
How can I fix this?
I found that ev.target refers to the div where item is being dropped, so contains('dropzone') always returns true.
this worked for me:
function drag(ev, source) {
ev.dataTransfer.setData("text", ev.target.id);
ev.dataTransfer.setData("parent", source.parentNode.tagName);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
var parent= ev.dataTransfer.getData("parent");
// console.log(parent);
if(parent == "A"){
el.appendChild(document.getElementById(data).cloneNode(true));
}
else{
ev.target.appendChild(document.getElementById(data));
}
}
Here you can store parentNode.tagName(either 'a' or 'div') of the dragged item into dataTransfer and access it in the drop() function, based on which you clone the item or simple move it.

Categories