How to add effect to drag and drop elements in java script - javascript

I have created a short exercise that involves 3 boxes that are attributed to certain shapes. I have it set now that if someone drags the shape to the correct box it is places in the box. However, currently if someone drags a shape to the wrong shape it only resets. I would like to add some effects such as, if the person drags to the wrong one it resets and a red flash appears on in the box, and if correct a green one appears. If possible it would be nice to be able to also have the red flash appear even if the person adds it to the correct box, but after the specified number such as a third triangle in the triangle box. How would this be done ? This is my current code
var circ = document.getElementById("c1");
var tria = document.getElementById("t1");
var squa = document.getElementById("s1");
var circ2 = document.getElementById("c2");
var tria2 = document.getElementById("t2");
var squa2 = document.getElementById("s2");
var dropt = document.getElementById("dzt");
var dropc = document.getElementById("dzc");
var drops = document.getElementById("dzs");
circ.ondragstart = function(evt) {
evt.dataTransfer.setData('key1', evt.target.id);
console.log("dragging circle");
}
tria.ondragstart = function(evt) {
evt.dataTransfer.setData('key2', evt.target.id);
console.log("dragging triangle");
}
squa.ondragstart = function(evt) {
evt.dataTransfer.setData('key3', evt.target.id);
console.log("dragging square");
}
/*circ2.ondragstart = function(){
evt.dataTransfer.setData('key4','c2');
console.log("yesh");
}
tria2.ondragstart=function(){
evt.dataTransfer.setData('key5','t2');
console.log("nani");
}
squa2.ondragstart=function(){
evt.dataTransfer.setData('key6','s1');
console.log("omae wa");
}
*/
dropt.ondragover = function(evt) {
evt.preventDefault();
console.log("over t");
}
dropc.ondragover = function(evt) {
evt.preventDefault();
console.log("over c");
}
drops.ondragover = function(evt) {
evt.preventDefault();
console.log("over s");
}
dropt.ondrop = function(evt) {
evt.preventDefault();
var icont = evt.dataTransfer.getData('key2');
console.log("drop t");
console.log(icont);
var current = document.getElementById(icont);
console.log(current);
var newcurrent = document.createElement('img');
newcurrent.src = current.src;
dropt.appendChild(newcurrent);
}
dropc.ondrop = function(evt) {
evt.preventDefault();
var iconc = evt.dataTransfer.getData('key1');
console.log("drop c");
console.log(iconc);
var current = document.getElementById(iconc);
console.log(current);
var newcurrent = document.createElement('img');
newcurrent.src = current.src;
dropc.appendChild(newcurrent);
}
drops.ondrop = function(evt) {
evt.preventDefault();
var icons = evt.dataTransfer.getData('key3');
console.log("drop s");
console.log(icons);
var current = document.getElementById(icons);
console.log(current);
var newcurrent = document.createElement('img');
newcurrent.src = current.src;
drops.appendChild(newcurrent);
}
#body {
width: 100%;
height: 100%;
}
.container {
display: flex;
}
.column {
flex: 1;
background: #ffffff;
border: 1px solid #ffffff;
box-sizing: border-box;
}
.column-one {
order: 3;
}
.column-two {
order: 1;
}
.column-three {
order: 4;
}
.column-four {
order: 2;
}
.column-five {
order: 5;
}
.drop-zone1 {
align-content: center;
<!--border-radius: 50%;
-->width: 150px;
height: 150px;
border: 2px;
border-style: solid;
border-color: #535f6b;
}
.drop-zone2 {
align-content: center;
<!--border-radius: 50%;
-->width: 150px;
height: 150px;
border: 2px;
border-style: solid;
border-color: #535f6b;
}
.drop-zone3 {
align-content: center;
<!--border-radius: 50%;
-->width: 150px;
height: 150px;
border: 2px;
border-style: solid;
border-color: #535f6b;
}
.icon1 {
width: 50px;
height: 50px;
margin-left: 45px;
}
.icon2 {
width: 50px;
height: 50px;
margin-left: 56px;
align-content: center;
}
.icon3 {
width: 50px;
height: 50px;
margin-left: 58px;
}
.question {
text-align: center;
color: #535f6b;
font-family: sans-serif;
font-style: italic;
}
<p class="question"><b>Drag and drop the elements to their corresponding set to achieve: <br>a. 3 circles in the circle set<br>b. 2 triangles in the triangle set<br>c. 5 squares in the square set</b></p>
<div class="container">
<div class="column column-one"><img src="circle.png" id="c1" style="margin-left: 55px"></div>
<div class="column column-two"></div>
<div class="column column-three"><img src="square.png" id="s1" style="margin-left: 58px"></div>
<div class="column column-four"><img src="triang.png" id="t1" style="margin-left: 45px"></div>
<div class="column column-five"></div>
</div>
<br>
<div class="container">
<div class="column column-one">
<div class="drop-zone1" id="dzt"></div>
</div>
<div class="column column-two"></div>
<div class="column column-three">
<div class="drop-zone2" id="dzc"></div>
</div>
<div class="column column-four">
<div class="drop-zone3" id="dzs"></div>
</div>
<div class="column column-five"></div>
</div>
<div class="container">
<div class="column column-one">
<div class="icon1"><img src="triang.png"></div>
</div>
<div class="column column-two"></div>
<div class="column column-three">
<div class="icon2"><img src="circle.png"></div>
</div>
<div class="column column-four">
<div class="icon3"><img src="square.png"></div>
</div>
<div class="column column-five"></div>
</div>
This is what it looks like with the images
Thanks in advance and best regards

In the below snippet I've added some condition to check if the object was dragged in its area, if so , I added the class that has an animation background ( annimation created at bottom ) otherwise it will check if the drag area has child ( do not trigger error annimation , else trigger the error annimation )
you can set your own annimation and colors by changing the both css annimations and the css class .green and .red
see below snippet
var circ = document.getElementById("c1");
var tria = document.getElementById("t1");
var squa = document.getElementById("s1");
var circ2 = document.getElementById("c2");
var tria2 = document.getElementById("t2");
var squa2 = document.getElementById("s2");
var dropt = document.getElementById("dzt");
var dropc = document.getElementById("dzc");
var drops = document.getElementById("dzs");
tria.ondragstart = function(evt) {
evt.dataTransfer.setData('key2', evt.target.id);
console.log("dragging triangle");
}
circ.ondragstart = function(evt) {
evt.dataTransfer.setData('key1', evt.target.id);
console.log("dragging circle");
}
squa.ondragstart = function(evt) {
evt.dataTransfer.setData('key3', evt.target.id);
console.log("dragging square");
}
/*circ2.ondragstart = function(){
evt.dataTransfer.setData('key4','c2');
console.log("yesh");
}
tria2.ondragstart=function(){
evt.dataTransfer.setData('key5','t2');
console.log("nani");
}
squa2.ondragstart=function(){
evt.dataTransfer.setData('key6','s1');
console.log("omae wa");
}
*/
dropt.ondragover = function(evt) {
evt.preventDefault();
//console.log("over t");
}
dropc.ondragover = function(evt) {
evt.preventDefault();
//console.log("over c");
}
drops.ondragover = function(evt) {
evt.preventDefault();
//console.log("over s");
}
dropt.ondrop = function(evt) {
evt.preventDefault();
var icont = evt.dataTransfer.getData('key2');
console.log("drop t");
console.log(icont);
var current = document.getElementById(icont);
console.log(current);
if(current != null) {
if(this.hasChildNodes()) return;
var newcurrent = document.createElement('img');
newcurrent.src = current.src;
this.appendChild(newcurrent);
setBackground("green",this);
}
else {
if(!this.hasChildNodes())
setBackground("red",this);
}
}
dropc.ondrop = function(evt) {
evt.preventDefault();
var iconc = evt.dataTransfer.getData('key1');
console.log("drop c");
console.log("dd",iconc);
var current = document.getElementById(iconc);
console.log(current);
if(current != null) {
if(this.hasChildNodes()) return;
var newcurrent = document.createElement('img');
newcurrent.src = current.src;
this.appendChild(newcurrent);
setBackground("green",this);
}
else {
if(!this.hasChildNodes())
setBackground("red",this);
}
}
drops.ondrop = function(evt) {
evt.preventDefault();
var icons = evt.dataTransfer.getData('key3');
console.log("drop s");
console.log(icons);
var current = document.getElementById(icons);
console.log(current);
if(current != null) {
if(this.hasChildNodes()) return;
var newcurrent = document.createElement('img');
newcurrent.src = current.src;
this.appendChild(newcurrent);
setBackground("green",this);
}
else {
if(!this.hasChildNodes())
setBackground("red",this);
}
}
function setBackground (className,node) {
node.classList.remove("green");
node.classList.remove("red");
node.classList.add(className);
}
#body {
width: 100%;
height: 100%;
}
.container {
display: flex;
}
.column {
flex: 1;
background: #ffffff;
border: 1px solid #ffffff;
box-sizing: border-box;
}
.column-one {
order: 3;
}
.column-two {
order: 1;
}
.column-three {
order: 4;
}
.column-four {
order: 2;
}
.column-five {
order: 5;
}
.drop-zone1 {
align-content: center;
<!--border-radius: 50%;
-->width: 150px;
height: 150px;
border: 2px;
border-style: solid;
border-color: #535f6b;
}
.drop-zone2 {
align-content: center;
<!--border-radius: 50%;
-->width: 150px;
height: 150px;
border: 2px;
border-style: solid;
border-color: #535f6b;
}
.drop-zone3 {
align-content: center;
<!--border-radius: 50%;
-->width: 150px;
height: 150px;
border: 2px;
border-style: solid;
border-color: #535f6b;
}
.icon1 {
width: 50px;
height: 50px;
margin-left: 45px;
}
.icon2 {
width: 50px;
height: 50px;
margin-left: 56px;
align-content: center;
}
.icon3 {
width: 50px;
height: 50px;
margin-left: 58px;
}
.question {
text-align: center;
color: #535f6b;
font-family: sans-serif;
font-style: italic;
}
.green {
animation-name: backgroundGreen;
animation-duration: 1.5s;
animation-iteration-count: 3;
background-color:#0f0;
}
.red {
animation-name: backgroundRed;
animation-duration: 1s;
animation-iteration-count: 3;
background-color:#f00;
}
/* The animation code */
#keyframes backgroundGreen {
0% {background-color:#fff;}
50% {background-color:#00ffbb;}
100% {background-color:#00ff00;}
}
#keyframes backgroundRed {
0% {background-color:#fff;}
50% {background-color:#ff0055;}
100% {background-color:#ff0000;}
}
<p class="question"><b>Drag and drop the elements to their corresponding set to achieve: <br>a. 3 circles in the circle set<br>b. 2 triangles in the triangle set<br>c. 5 squares in the square set</b></p>
<div class="container">
<div class="column column-one"><img src="https://cdn1.iconfinder.com/data/icons/material-core/20/check-circle-outline-blank-128.png" id="c1" style="margin-left: 55px"></div>
<div class="column column-two"></div>
<div class="column column-three"><img src="https://cdn1.iconfinder.com/data/icons/feather-2/24/square-128.png" id="s1" style="margin-left: 58px"></div>
<div class="column column-four"><img src="https://cdn1.iconfinder.com/data/icons/feather-2/24/triangle-128.png" id="t1" style="margin-left: 45px"></div>
<div class="column column-five"></div>
</div>
<br>
<div class="container">
<div class="column column-one">
<div class="drop-zone1" id="dzt"></div>
</div>
<div class="column column-two"></div>
<div class="column column-three">
<div class="drop-zone2" id="dzc"></div>
</div>
<div class="column column-four">
<div class="drop-zone3" id="dzs"></div>
</div>
<div class="column column-five"></div>
</div>
<div class="container">
<div class="column column-one">
<div class="icon1"><img src="https://cdn1.iconfinder.com/data/icons/feather-2/24/triangle-64.png"></div>
</div>
<div class="column column-two"></div>
<div class="column column-three">
<div class="icon2"><img src="https://cdn1.iconfinder.com/data/icons/material-core/20/check-circle-outline-blank-64.png"></div>
</div>
<div class="column column-four">
<div class="icon3"><img src="https://cdn1.iconfinder.com/data/icons/feather-2/24/square-64.png"></div>
</div>
<div class="column column-five"></div>
</div>

Related

Stumbled upon a puzzling issue, I'm unable to make a carousel image lead to an address in href via touch on a mobile phone

So this is my first time ever posting on stackoverflow, Usually I'm simply scouring for an answer I need , however this time after long time of searching for solutions and trying out different solutions, I've decided to try and ask some of the smart people on stackoverflow , I'm simply unable to make an image inside of a carousel to be clickable and lead to an address inside of its "href" link , on any computer this works correctly, however on the mobile phone it's just not .
I'm stumped i don't know if its related to an touch event handler+touchfingerpress event , or to it being inside of a carousel div overlapping, tried clearfix class, tried, different solutions, so far no luck lol.
this is the entire code with placeholder links for images and the rest, but you can see the mechanism none the less in this live w3space fiddle : https://menk-s-space.w3spaces.com/carousel.html
or the entire link in plain:
thanks for the helpers. I would love to learn and improve!
<!-- partial:index.partial.html -->
<div class="bootstrap-iso clearfix">
<div id="slider9" class="slider9 clearfix">
<div id="slide9r" class="slide9r clearfix d-flex aligns-items-center justify-content-center" >
<div class="wrapper9 clearfix" >
<div id="slide9s" class="slide9s clearfix" >
<span class="slide9 clearfix" >
<div class="gallery">
<a target="_blank" href="portfolio.php">
<img src="portfolio/portfolio1.png" alt="Cinque Terre">
</a>
<div class="desc">portfolio0</div>
<div class="portfolio-item-meta clearfix">
<h5>portfolio0</h5>
<p>PC solutions</p>
</div>
</div>
</span>
<span class="slide9 clearfix">
<div class="gallery">
<a target="_blank" href="portfolio1.php">
<img src="portfolio/portfolio2.png" alt="Forest" >
</a>
<div class="desc">portfolio1</div>
<div class="portfolio-item-meta clearfix">
<h5>portfolio1</h5>
<p>PC solutions</p>
</div>
</div>
</span>
<span class="slide9">
<div class="gallery">
<a target="_blank" href="portfolio2.php">
<img src="portfolio4.png" alt="Northern Lights">
</a>
<div class="desc">portfolio4</div>
<div class="portfolio-item-meta clearfix">
<h5>portfolio</h5>
<p>PC solutions</p>
</div>
</div>
</span>
<span class="slide9">
<div class="gallery">
<a target="_blank" href="portfolio3.php">
<img src="portfolio/portfolio5.png" alt="Mountains">
</a>
<div class="desc">portfolio6</div>
<div class="portfolio-item-meta clearfix">
<h5>portfolio5</h5>
<p>PC solutions</p>
</div>
</div>
</span>
<!-- <span class="slide9">slide9 5</span>-->
</div>
</div>
<a id="prev" class="control prev"></a>
<a id="next" class="control next"></a>
</div>
</div>
</div>
<!-- partial -->
<script src="js/script.js"></script>
<style>
#import url("css?family=Roboto");
* {
box-sizing: border-box;
}
text-align: center;
letter-spacing: 0.15em;
font-size: 22px;
}
.slide9r {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 300px;
box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2);
}
.wrapper9 {
position: relative;
width: 400px;
height: 300px;
z-index: 1;
}
.slide9s {
display: flex;
position: relative;
top: 0;
left: -400px;
width: 10000px;
}
.slide9s.shifting {
transition: left 0.2s ease-out;
}
.slide9 {
width: 400px;
height: 300px;
cursor: pointer;
display: flex;
flex-direction: column;
justify-content: center;
transition: all 1s;
position: relative;
background: #FFCF47;
border-radius: 2px;
}
.slide9r.loaded .slide9:nth-child(2),
.slide9r.loaded .slide9:nth-child(7) {
/*background: #FFCF47;*/
background:#7adcef00;
}
.slide9r.loaded .slide9:nth-child(1),
.slide9r.loaded .slide9:nth-child(6) {
/*background: #7ADCEF;*/
background:#7adcef00;
}
.slide9r.loaded .slide9:nth-child(3) {
/*background: #3CFF96;*/
background:#7adcef00;
}
.slide9r.loaded .slide9:nth-child(4) {
/*background: #a78df5;*/
background:#7adcef00;
}
.slide9r.loaded .slide9:nth-child(5) {
/*background: #ff8686;*/
background:#7adcef00;
}
.control {
position: absolute;
top: 50%;
width: 50px;
height: 50px;
background: #fff;
border-radius: 50px;
margin-top: -20px;
box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.3);
z-index: 2;
}
.prev,
.next {
background-size: 22px;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
.prev {
background-image: url(ChevronLeft-512.png);
left: -20px;
display: none;
}
.next {
background-image: url(ChevronRight-512.png);
right: -20px;
display: none;
}
.prev:active,
.next:active {
transform: scale(0.8);
}
div.gallery {
margin: 5px;
border: 1px solid #ccc;
float: left;
}
div.gallery:hover {
border: 1px solid #777;
}
div.gallery img {
width: 100%;
height: auto;
}
div.desc {
padding: 15px;
text-align: center;
}</style>
<script>
var slide9r = document.getElementById('slide9r'),
slide9rItems = document.getElementById('slide9s'),
prev = document.getElementById('prev'),
next = document.getElementById('next');
function slide9(wrapper9, items, prev, next) {
var posX1 = 0,
posX2 = 0,
posInitial,
posFinal,
threshold = 100,
slide9s = items.getElementsByClassName('slide9'),
slide9sLength = slide9s.length,
slide9Size = items.getElementsByClassName('slide9')[0].offsetWidth,
firstslide9 = slide9s[0],
lastslide9 = slide9s[slide9sLength - 1],
cloneFirst = firstslide9.cloneNode(true),
cloneLast = lastslide9.cloneNode(true),
index = 0,
allowShift = true;
// Clone first and last slide9
items.appendChild(cloneFirst);
items.insertBefore(cloneLast, firstslide9);
wrapper9.classList.add('loaded');
// Mouse events
items.onmousedown = dragStart;
// Touch events
items.addEventListener('touchstart', dragStart);
items.addEventListener('touchend', dragEnd);
items.addEventListener('touchmove', dragAction);
// Click events
prev.addEventListener('click', function () { shiftslide9(-1) });
next.addEventListener('click', function () { shiftslide9(1) });
// Transition events
items.addEventListener('transitionend', checkIndex);
function dragStart (e) {
e = e || window.event;
e.preventDefault();
posInitial = items.offsetLeft;
if (e.type == 'touchstart') {
posX1 = e.touches[0].clientX;
} else {
posX1 = e.clientX;
document.onmouseup = dragEnd;
document.onmousemove = dragAction;
}
}
function dragAction (e) {
e = e || window.event;
if (e.type == 'touchmove') {
posX2 = posX1 - e.touches[0].clientX;
posX1 = e.touches[0].clientX;
} else {
posX2 = posX1 - e.clientX;
posX1 = e.clientX;
}
items.style.left = (items.offsetLeft - posX2) + "px";
}
function dragEnd (e) {
posFinal = items.offsetLeft;
if (posFinal - posInitial < -threshold) {
shiftslide9(1, 'drag');
} else if (posFinal - posInitial > threshold) {
shiftslide9(-1, 'drag');
} else {
items.style.left = (posInitial) + "px";
}
document.onmouseup = null;
document.onmousemove = null;
}
function shiftslide9(dir, action) {
items.classList.add('shifting');
if (allowShift) {
if (!action) { posInitial = items.offsetLeft; }
if (dir == 1) {
items.style.left = (posInitial - slide9Size) + "px";
index++;
} else if (dir == -1) {
items.style.left = (posInitial + slide9Size) + "px";
index--;
}
};
allowShift = false;
}
function checkIndex (){
items.classList.remove('shifting');
if (index == -1) {
items.style.left = -(slide9sLength * slide9Size) + "px";
index = slide9sLength - 1;
}
if (index == slide9sLength) {
items.style.left = -(1 * slide9Size) + "px";
index = 0;
}
allowShift = true;
}
}
slide9(slide9r, slide9rItems, prev, next);
</script>
Tried clearfix in hopes of a div overlapping but didn't work, tried looking into eventhandlers for touch but i'm not on that level yet.
tried different carousels mechanisms , still didn't work.
tried outside of the carousel , it seemed to work, but than i lose the carousel functionality.
Would love someone to enlighten me , i want for any image in the carousel upon clicking for it to lead to another page within the href address on a mobile phone with a touch screen.
Thanks for the helpers !
Simpler example which causes the same issue:
document.querySelector('p').addEventListener('touchstart', e => {
e.preventDefault()
})
<a href="?123=2">
<p>test</p>
</a>
The problem is a typo in your <style> tag. Change this:
* {
box-sizing: border-box;
}
text-align: center;
letter-spacing: 0.15em;
font-size: 22px;
}
to
* {
box-sizing: border-box;
/* text-align: center;
letter-spacing: 0.15em;
font-size: 22px; */
}
I commented those 3 lines, because it messes the styles, but you can uncomment them if you need them.
Also tested the fix on a CodeSandbox too and it's working.
Furthermore, I added a debounce function for your dragStart so the drag will not interfere with your click event.
...
const debounce = (callback, wait) => {
let timeoutId = null;
return (...args) => {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
callback.apply(null, args);
}, wait);
};
}
...
const debouncedDragStart = debounce(dragStart, 100);
...
items.addEventListener("touchstart", debouncedDragStart);

Refactor my javascript code and I need a way how to prevent the text repeated when the mouse on?

Hi guys I’m a beginner in JS could somebody help me please
I have created an HTML page with 3 country’s flags. When the user moves the mouse over one of the flags, display the name of the country in the text box. When they move the mouse away from the flag, clear the text box.
The problem is when I move the mouse on the flag many times the text repeated
Also how to refactor my code it is so repeated I know I must use foreach but how? here is my code
const photo = Array.from(document.querySelectorAll('.flag-img'));
const oman = document.querySelector('.oman');
const algeria = document.querySelector('.algeria');
const uae = document.querySelector('.uae');
const div1 = document.createElement("div1");
const div2 = document.createElement("div2");
const div3 = document.createElement("div3");
function countryName() {
const text1 = document.createTextNode("Oman");
div1.appendChild(text1);
div1.className = "box";
oman.appendChild(div1);
}
function countryAlg() {
const text2 = document.createTextNode("Algeria");
div2.appendChild(text2);
div2.className = "box";
algeria.appendChild(div2);
}
function countryUae() {
const text3 = document.createTextNode("UAE");
div3.appendChild(text3);
div3.className = "box";
uae.appendChild(div3);
}
function fadeOut() {
div1.parentNode.removeChild(div1);
}
function fadeOut2() {
div2.parentNode.removeChild(div2);
}
function fadeOut3() {
div3.parentNode.removeChild(div3);
}
oman.addEventListener('mouseenter', countryName);
algeria.addEventListener('mouseenter', countryAlg);
uae.addEventListener('mouseenter', countryUae);
oman.addEventListener('mouseleave', fadeOut);
algeria.addEventListener('mouseleave', fadeOut2);
uae.addEventListener('mouseleave', fadeOut3);
* {
margin: 0;
box-sizing: border-box;
}
header {
text-align: center;
}
#flag {
margin-top: 50px;
display: flex;
justify-content: space-around;
}
.flag-img img {
width: 200px;
}
.box {
text-align: center;
padding: 20px;
border: 2px solid black;
width: 100px;
height: 100px;
background-color: transparent;
color: black;
/*position: absolute;
left: 50px;
top: 50px;*/
}
<header>
<h1>Countries Flags</h1>
</header>
<div id="flag">
<div class="flag-img oman">
<img src="https://motionarray.imgix.net/preview-339277phSMy7aPd_0007.jpg?w=750&q=60&fit=max&auto=format">
</div>
<div class="flag-img algeria">
<img src="https://img.freepik.com/free-photo/flag-of-algeria_1401-52.jpg?size=338&ext=jpg">
</div>
<div class="flag-img uae">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Flag_of_the_United_Arab_Emirates.svg/255px-Flag_of_the_United_Arab_Emirates.svg.png">
</div>
</div>
I tried to refractor this in your way :
Select all your elements
var flags = document.getElementsByClassName("flag-img");
Init elements with function.
for (var i = 0; i < flags.length; i++) {
(function () {
console.log(flags[i]);
var elem = flags[i];
flags[i].addEventListener('mouseenter', function() {
showCountry(elem)
}, false);
flags[i].addEventListener('mouseleave', function() {
fadeOut(elem)
}, false);
}());
}
Single function fadeout
function fadeOut(a) {
a.removeChild(a.lastChild);
}
Single function show.
function showCountry(a) {
const text = document.createTextNode(a.className.split(" ")[1]);
var div = document.createElement("div");
div.appendChild(text);
div.className = "box";
a.appendChild(div);
}
console.clear();
var flags = document.getElementsByClassName("flag-img");
for (var i = 0; i < flags.length; i++) {
(function () {
var elem = flags[i];
flags[i].addEventListener('mouseenter', function() {
showCountry(elem)
}, false);
flags[i].addEventListener('mouseleave', function() {
fadeOut(elem)
}, false);
}());
}
function fadeOut(a) {
a.removeChild(a.lastChild);
}
function showCountry(a) {
const text = document.createTextNode(a.className.split(" ")[1]);
var div = document.createElement("div");
div.appendChild(text);
div.className = "box";
a.appendChild(div);
}
* {
margin: 0;
box-sizing: border-box;
}
header {
text-align: center;
}
#flag {
margin-top: 50px;
display: flex;
justify-content: space-around;
}
.flag-img img {
width: 200px;
}
.box {
text-align: center;
padding: 20px;
border: 2px solid black;
width: 100px;
height: 100px;
background-color: transparent;
color: black;
/*position: absolute;
left: 50px;
top: 50px;*/
}
<header>
<h1>Countries Flags</h1>
</header>
<div id="flag">
<div class="flag-img oman">
<img src="https://motionarray.imgix.net/preview-339277phSMy7aPd_0007.jpg?w=750&q=60&fit=max&auto=format">
</div>
<div class="flag-img algeria">
<img src="https://img.freepik.com/free-photo/flag-of-algeria_1401-52.jpg?size=338&ext=jpg">
</div>
<div class="flag-img uae">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Flag_of_the_United_Arab_Emirates.svg/255px-Flag_of_the_United_Arab_Emirates.svg.png">
</div>
</div>
instead of for loop I used forEach because i hate for loops
and the code worked
var flags = Array.from(document.getElementsByClassName("flag-img"));
flags.forEach(function(value) {
value.addEventListener('mouseenter', function() {
showCountry(value)
}, false);
value.addEventListener('mouseleave', function() {
fadeOut(value)
}, false);
});
function fadeOut(a) {
a.removeChild(a.lastChild);
}
function showCountry(a) {
const text = document.createTextNode(a.className.split(" ")[1]);
var div = document.createElement("div");
div.appendChild(text);
div.className = "box";
a.appendChild(div);
}
I know you're trying to learn Javascript, but this is far easier (and better performance-wise) to achieve using CSS only:
#flag {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
#flag img {
max-width: 100%;
}
.flag-img::after {
display: block;
content: attr(data-country);
opacity: 0;
text-align: center;
transition: opacity .4s ease-in-out;
}
.flag-img:hover::after {
opacity: 1;
}
<div id="flag">
<div class="flag-img" data-country="Oman">
<img src="https://motionarray.imgix.net/preview-339277phSMy7aPd_0007.jpg?w=750&q=60&fit=max&auto=format">
</div>
<div class="flag-img" data-country="Algeria">
<img src="https://img.freepik.com/free-photo/flag-of-algeria_1401-52.jpg?size=338&ext=jpg">
</div>
<div class="flag-img" data-country="United Arab Emirate">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Flag_of_the_United_Arab_Emirates.svg/255px-Flag_of_the_United_Arab_Emirates.svg.png">
</div>
</div>

Function Running Before Parameters Available

I am making a tic tac toe game with HTMl CSS (SCSS) and JS, and I am running into some trouble. I have a function to add an X or O to each grid space, but it is adding them automatically before it even has the right parameters to do ir, but it is doing it right(ish). Can someone help?
I also have it here.
My HTML:
<div class="wrap">
<div class="piece one"></div>
<div class="piece two"></div>
<div class="piece three"></div>
<div class="piece four"></div>
<div class="piece five"></div>
<div class="piece six"></div>
<div class="piece seven"></div>
<div class="piece eight"></div>
<div class="piece nine"></div>
</div>
My CSS:
body {
margin: 0;
overflow: hidden;
}
.wrap {
position: absolute;
height: 500px;
width: 510px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-wrap: wrap;
align-content: flex-start;
}
.piece {
width: calc(500px / 3);
height: calc(500px / 3);
background: white;
cursor: pointer;
}
.five, .two, .eight {
border-left: 5px solid black;
border-right: 5px solid black;
}
.one, .two, .three {
border-bottom: 5px solid black;
}
.seven, .eight, .nine {
border-top: 5px solid black;
}
.x {
margin-left: 30px;
margin-top: 20px;
display: flex;
.line {
height: calc(400px / 3);
width: 5px;
background: black;
&Two {
transform: rotate(-45deg);
margin-left: -5px;
}
&One {
transform: rotate(45deg);
margin-left: 50px;
}
}
}
.o {
margin-left: 30px;
margin-top: 20px;
height: 100px;
width: 100px;
border-radius: 100%;
border: 5px solid black;
}
And my JS:
let x = true,
o = false,
AI = false,
easy = true,
med = false,
hard = false;
const one = document.querySelector(".one"),
two = document.querySelector(".two"),
three = document.querySelector(".three"),
four = document.querySelector(".four"),
five = document.querySelector(".five"),
six = document.querySelector(".six"),
seven = document.querySelector(".seven"),
eight = document.querySelector(".eight"),
nine = document.querySelector(".nine"),
X /* The diference between this X and the other x is that this one is capitalized, same w/ the O and o */ = "<div class='x'><div class='lineOne line'></div><div class='lineTwo line'></div></div>",
O = "<div class='o'></div>";
one.addEventListener("click", function() {
console.log("goodness happened")
})
const tic = function(square) {
console.log("test 1 success");
if (x === true) {
square.innerHTML = X;
x = false;
o = true;
}
else {
square.innerHTML = O;
x = true;
o = false;
}
}
one.addEventListener("click", tic(one), false)
two.addEventListener("click", tic(two), false)
three.addEventListener("click", tic(three), false)
four.addEventListener("click", tic(four), false)
five.addEventListener("click", tic(five), false)
six.addEventListener("click", tic(six), false)
seven.addEventListener("click", tic(seven), false)
eight.addEventListener("click", tic(eight), false)
nine.addEventListener("click", tic(nine), false)
Sorry it is a lot. I just want to give you the full picture. Thanks in advance!
You're calling the function instead of referencing it, change all the event handlers to use an anonymous function instead
one.addEventListener("click", function() {
tic(one)
}, false);

How to make this animation properly with jQuery

I am trying to make an animation, you can see my efforts at jsfiddle. And here is the code I've used:
/* JavaScript: */
var app = function () {
var self = this;
var allBoxes = $('.box');
var shadow = $('#shadow');
var busy = false;
self.init = function () {
self.events();
};
self.getBoxLeftPosition = function(id)
{
var left = 100;
if (id == 'box2')
{
left = 300;
} else if (id == 'box3')
{
left = 500;
} else if (id == 'box4')
{
left = 700;
}
return left;
};
self.events = function () {
allBoxes.on('hover mousemove', function(event) {
event.stopPropagation();
var currentBox = $(this);
if (currentBox.hasClass('inactive') && !busy)
{
busy = true;
currentBox.removeClass('inactive').addClass('active').animate({
left: '-=30',
width: 260
}, 400, function () {
busy = false;
});
shadow.fadeIn(400);
}
});
$('body').mousemove(function(event) {
var currentBox = $('.active');
var leftValue = self.getBoxLeftPosition(currentBox.attr('id'));
if (currentBox.length > 0)
{
currentBox.stop();
currentBox.animate({
left: leftValue,
width: 200
}, 300, 'swing', function () {
currentBox.removeClass('active').addClass('inactive');
}, 300);
shadow.fadeOut(300);
}
});
};
return self;
};
var main = new app();
main.init();
/* CSS: */
html, body {
margin: 0;
}
.box {
position: absolute;
top: 120px;
width: 200px;
height: 420px;
}
.box div {
text-align: center;
color: white;
position: absolute;
top: 200px;
left: 0;
right: 0;
font-size: 25px;
font-weight: bold;
}
#box1 {
left: 100px;
background: pink;
}
#box2 {
left: 300px;
background: skyblue;
}
#box3 {
left: 500px;
background: orange;
}
#box4 {
left: 700px;
background: lightgreen;
}
#shadow {
display: none;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url('https://lh6.googleusercontent.com/Vz0GTzpQVaxmlIvvGgg64CSxcYBbHzu7gMQERduJ4qjU5HAg8KfisFFQvIqvKL5Vn7LIy6HZ=w1920-h916');
z-index: 10;
}
.inactive {
z-index: 5;
}
.active {
z-index: 20;
}
<!-- HTML: -->
<div id="box1" class="box inactive">
<div id="copy1">Copy 1</div>
</div>
<div id="box2" class="box inactive">
<div id="copy2">Copy 2</div>
</div>
<div id="box3" class="box inactive">
<div id="copy3">Copy 3</div>
</div>
<div id="box4" class="box inactive">
<div id="copy4">Copy 4</div>
</div>
<div id="shadow"></div>
Here is what I am trying to achieve in words: I have 4 boxes and whenever a user hovers over one of them that box needs to expand a little and everything else needs to be grayed out and whenever the mouse leaves the box it needs to go back to it's original state.
In my jsfiddle I got it working to a point but it's buggy.
take a look at this JSFiddle
$('.box').hover(function(){
$(this).siblings().addClass('inactive');
}, function(){
$(this).siblings().removeClass('inactive');
});
tried to do it with pure css but sadly there's no such thing as prev sibling selector in css. Its kinda jumpy because of z-index getting immediately change on hover.
You can achieve the same effect even with CSS
$(document).on('mouseenter', '.item', function(e){
var me = $(this);
$('.item').not(this).addClass('greyed');
});
$(document).on('mouseleave', '.item', function(e){
$('.item').removeClass('greyed');
});
ul,li{
list-style:none;padding:0;margin:0;
}
ul{
width:400px;
}
li, .item {
width:100px;
height:100px;
}
li {
float:left;
position:relative;
}
.item {
background-color: #eee;
border:1px solid #ccc;
position:absolute;
z-index:1;
-webkit-transition:all 0.3s ease-in-out;
}
.item:hover {
width:110px;
z-index:2;
}
.red{
background: red;
}
.pink{
background: pink;
}
.blue{
background: blue;
}
.yellow{
background: yellow;
}
.greyed{
-webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
filter: grayscale(100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<ul>
<li>
<div class="item red"></div>
</li>
<li>
<div class="item blue"></div>
</li>
<li>
<div class="item yellow"></div>
</li>
<li>
<div class="item pink"></div>
</li>
</ul>
Here is what I did.
First, I found that the background image in your css is not a valid resource, so I replaced it with regular background color (it's transparent black, you may want to adjust it).
Second, I changed allBoxes.on('hover mousemove' to allBoxes.on('mouseover', and $('body').mousemove to allBoxes.on('mouseout'.
Third, I removed the $busy flag tracking.
Fourth, I changed var currentBox = $('.active'); to var currentBox = $(event.target);.
var app = function () {
var self = this;
var allBoxes = $('.box');
var shadow = $('#shadow');
var busy = false;
self.init = function () {
self.events();
};
self.getBoxLeftPosition = function(id)
{
var left = 100;
if (id == 'box2')
{
left = 300;
} else if (id == 'box3')
{
left = 500;
} else if (id == 'box4')
{
left = 700;
}
return left;
};
self.events = function () {
allBoxes.on('mouseover', function(event) {
event.stopPropagation();
var currentBox = $(this);
if (currentBox.hasClass('inactive') && !busy)
{
//busy = true;
currentBox.removeClass('inactive').addClass('active').animate({
left: '-=30',
width: 260
}, 400, function () {
//busy = false;
});
shadow.fadeIn(400);
}
});
allBoxes.on('mouseout', function(event) {
var currentBox = $(event.target);
var leftValue = self.getBoxLeftPosition(currentBox.attr('id'));
if (currentBox.length > 0)
{
currentBox.stop();
currentBox.animate({
left: leftValue,
width: 200
}, 300, 'swing', function () {
currentBox.removeClass('active').addClass('inactive');
}, 300);
shadow.fadeOut(300);
}
});
};
return self;
};
var main = new app();
main.init();
html, body {
margin: 0;
}
.box {
position: absolute;
top: 120px;
width: 200px;
height: 420px;
}
.box div {
text-align: center;
color: white;
position: absolute;
top: 200px;
left: 0;
right: 0;
font-size: 25px;
font-weight: bold;
}
#box1 {
left: 100px;
background: pink;
}
#box2 {
left: 300px;
background: skyblue;
}
#box3 {
left: 500px;
background: orange;
}
#box4 {
left: 700px;
background: lightgreen;
}
#shadow {
display: none;
position: absolute;
left: 0;
top: 0;
width: 1000px;
height: 600px;
/*background: url('https://lh6.googleusercontent.com/Vz0GTzpQVaxmlIvvGgg64CSxcYBbHzu7gMQERduJ4qjU5HAg8KfisFFQvIqvKL5Vn7LIy6HZ=w1920-h916');*/
background-color: rgba(0,0,0,0.5); /* transparent black */
z-index: 10;
}
.inactive {
z-index: 5;
}
.active {
z-index: 20;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="box1" class="box inactive">
<div id="copy1">Copy 1</div>
</div>
<div id="box2" class="box inactive">
<div id="copy2">Copy 2</div>
</div>
<div id="box3" class="box inactive">
<div id="copy3">Copy 3</div>
</div>
<div id="box4" class="box inactive">
<div id="copy4">Copy 4</div>
</div>
<div id="shadow"></div>

Javascript Todolist category if else statement

Hello I'm stuck on how to add category for my to do list. When you click on Button of category need change class name. I don't understand how to correctly write if/else statement when button is clicked.
plan how it need to work
Write task name
Choose Category
Add new task
May be somebody can help me out ore give some advice how to solve this problem!
Sorry for my english and if my question is to badly explained!
var toDoList = function() {
var addNewTask = function() {
var input = document.getElementById("taks-input").value,
itemTexts = input,
colA = document.getElementById('task-col-a').children.length,
colB = document.getElementById('task-col-b').children.length,
taskBoks = document.createElement("div"),
work = document.getElementById("work"),
Category = "color-2",
taskCount = 1;
if (work.onclick === true) {
var Category = "color";
}
taskBoks.className = "min-box";
taskBoks.innerHTML = '<div class="col-3 chack" id="task_' + (taskCount++) + '"><i class="fa fa-star"></i></div><div class="col-8 task-text" id="taskContent"><p>' + itemTexts + '</p><span id="time-now"></span></div><div class="col-1 ' + (Category) + '"></div>'
if (colB < colA) {
var todolist = document.getElementById("task-col-b");
} else {
var todolist = document.getElementById("task-col-a");
}
//todolist.appendChild(taskBoks);
todolist.insertBefore(taskBoks, todolist.childNodes[0]);
},
addButton = function() {
var btn2 = document.getElementById("add-task-box");
btn2.onclick = addNewTask;
};
addButton()
}
toDoList();
p {
padding: 20px 20px 20px 45px;
}
.chack {
background-color: #4c4b62;
height: 100%;
width: 40px;
}
.task-text {
background-color: #55566e;
height: 100%;
width: 255px;
}
.color {
width: 5px;
height: 100%;
background-color: #fdcd63;
float: right;
}
.color-2 {
width: 5px;
height: 100%;
background-color: red;
float: right;
}
.color-3 {
width: 5px;
height: 100%;
background-color: purple;
float: right;
}
.task {
height: 100px;
width: 300px;
border: 1px solid #fff;
float: left;
}
.chack,
.task-text {
float: left;
}
.add-new-task {
margin-bottom: 50px;
height: 80px;
width: 588px;
background-color: rgb(85, 86, 110);
padding-top: 30px;
padding-left: 15px;
}
.min-box {
height: 100px;
border-bottom: 1px solid #fff;
}
.center {
padding-top: 20px;
padding-left: 50px;
}
.fa-star {
padding-left: 14px;
padding-top: 100%;
}
#add-task-box {
float: right;
margin-right: 10px;
margin-top: -7px;
border: none;
background-color: rgb(255, 198, 94);
padding: 10px;
}
#taks-input {
height: 30px;
width: 350px;
margin-top: -7px;
}
.category {
margin-top: 10px;
}
<div class="container">
<div class="add-new-task">
<input type="text" id="taks-input">
<button id="add-task-box">Add New Task box</button>
<div class="category">
<button class="catBtn" id="work">Work</button>
<button class="catBtn" id="home">Home</button>
<button class="catBtn" id="other">Other</button>
</div>
</div>
<div class="lg-task" id="bigTask"></div>
<div class="task" id="task-col-a"></div>
<div class="task" id="task-col-b"></div>
</div>
you need to bind click event to your buttons and store that value in Category, so in you js add this
var toDoList = function() {
// set to default
var Category = "color-3";
// attach event to buttons
var catButtons = document.getElementsByClassName("catBtn");
// assign value based on event
var myCatEventFunc = function() {
var attribute = this.getAttribute("id");
if (attribute === 'work') {
Category = 'color';
} else if (attribute === 'home') {
Category = 'color-2';
}
};
for (var i = 0; i < catButtons.length; i++) {
catButtons[i].addEventListener('click', myCatEventFunc, false);
}
Demo: Fiddle
and remove this code from addNewTask function
if (work.onclick === true) {
var Category = "color";
}
It is a bit hard to understand what you are doing, what you are going for (a module of some kind?). You were not that far away from a working state.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Task</title>
<style>
p {
padding: 20px 20px 20px 45px;
}
.chack {
background-color: #4c4b62;
height: 100%;
width: 40px;
}
.task-text {
background-color: #55566e;
height: 100%;
width: 255px;
}
.color {
width: 5px;
height: 100%;
background-color: #fdcd63;
float: right;
}
.color-2 {
width: 5px;
height: 100%;
background-color: red;
float: right;
}
.color-3 {
width: 5px;
height: 100%;
background-color: purple;
float: right;
}
.task {
height: 100px;
width: 300px;
border: 1px solid #fff;
float: left;
}
.chack,
.task-text {
float: left;
}
.add-new-task {
margin-bottom: 50px;
height: 80px;
width: 588px;
background-color: rgb(85, 86, 110);
padding-top: 30px;
padding-left: 15px;
}
.min-box {
height: 100px;
border-bottom: 1px solid #fff;
}
.center {
padding-top: 20px;
padding-left: 50px;
}
.fa-star {
padding-left: 14px;
padding-top: 100%;
}
#add-task-box {
float: right;
margin-right: 10px;
margin-top: -7px;
border: none;
background-color: rgb(255, 198, 94);
padding: 10px;
}
#taks-input {
height: 30px;
width: 350px;
margin-top: -7px;
}
.category {
margin-top: 10px;
}
</style>
<script>
var toDoList = function() {
var addNewTask = function() {
var input = document.getElementById("taks-input").value,
itemTexts = input,
colA = document.getElementById('task-col-a').children.length,
colB = document.getElementById('task-col-b').children.length,
taskBoks = document.createElement("div"),
work = document.getElementById("work"),
Category = "color-2",
taskCount = 1;
if (work.onclick === true) {
Category = "color";
}
taskBoks.className = "min-box";
taskBoks.innerHTML = '<div class="col-3 chack" id="task_'
+ (taskCount++) +
'"><i class="fa fa-star"></i></div><div class="col-8 task-text" id="taskContent"><p>'
+ itemTexts +
'</p><span id="time-now"></span></div><div class="col-1 '
+ (Category) + '"></div>'
if (colB < colA) {
var todolist = document.getElementById("task-col-b");
} else {
var todolist = document.getElementById("task-col-a");
}
//todolist.appendChild(taskBoks);
todolist.insertBefore(taskBoks, todolist.childNodes[0]);
},
// I don't know what to do with that?
addButton = function() {
var btn2 = document.getElementById("add-task-box");
btn2.onclick = addNewTask();
};
// return the stuff you want to have public
return {
addNewTask:addNewTask
};
}
var f;
// wait until all HTML is loaded and put the stuff from above into the variable `f`
// you can call it with f.someFunction() in your case f.addNewTask()
window.onload = function(){
f = toDoList();
}
</script>
</head>
<body>
<div class="container">
<div class="add-new-task">
<input type="text" id="taks-input">
<button id="add-task-box" onclick="f.addNewTask()">Add New Task box</button>
<div class="category">
<button class="catBtn" id="work" >Work</button>
<button class="catBtn" id="home">Home</button>
<button class="catBtn" id="other">Other</button>
</div>
</div>
<div class="lg-task" id="bigTask"></div>
<div class="task" id="task-col-a"></div>
<div class="task" id="task-col-b"></div>
</div>
</body>
</html
I hope you understood what I did?

Categories