clearInterval on click - javascript

I have a simple script where random keywords appear at a timed interval. What I'd like is for them to stop appearing after one is clicked on.
Here's what I have so far:
function generate() {
$("[id*='keyword']").each(function(){
$(this).removeClass("show");
})
var number= Math.floor(Math.random() * 5) + 1
$("#keyword"+number).addClass("show");
}
$(function(){
setInterval(generate, 4000);
})
$("[id*='keyword']").click(function() {
clearInterval(generate);
});
div[id*='keyword']{
background: #aaa;
position: absolute;
left: -200px;
opacity: 0;
width:200px;
line-height: 60px;
text-align: center;
color: white;
height: 60px;
-webkit-transition: 1s all ease;
transition: 1s all ease;
}
div[id*='keyword'].show{
left: 0;
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="keyword1" class="keyword">
<h3>Keyword1</h3>
</div>
<div id="keyword2" class="keyword">
<h3>Keyword2</h3>
</div>
<div id="keyword3" class="keyword">
<h3>Keyword3</h3>
</div>
The random keyword appearing works fine, but the clearInterval function is not. I feel like I'm missing something simple here.
Thanks!

do like that way,
var intervalTime=0;
$(function(){
intervalTime = setInterval(generate, 4000);
})
$("[id*='keyword']").click(function() {
clearInterval(intervalTime);
});

change two lines of your code like the following:
window.intervalID = setInterval(generate, 4000);
and
clearInterval(window.intervalID);

Related

Auto load and unload element

The below snippet will load an element on page load using jquery,css, and javascript.
$('.callqueue').click(function(){
$('#dddnav').toggleClass('menu-open');
$('body').toggleClass('menu-open');
});
$(window).load(function (){
$('#dddnav').toggleClass('menu-open');
});
#man {
display:none;
}
#dddnav {
height:30%;
background:#333;
position:fixed;
top:0;
right:-270px;
width:300px;
transition:right .5s;
-webkit-transition:right .5s;
}
#dddnav.menu-open {
right:0;
transition:right .5s;
-webkit-transition:right .5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button class="callqueue"> CLICK </button>
<div id="dddnav" style="background: red; top: 10%;">
<img id="man" src="http://placehold.it/200" />
</div>
However, I want the element to load after 3 seconds after the page load, and to unload it after 5 seconds without having to click on the button. How can I get this done using javascript? I found this link: https://css-tricks.com/forums/topic/toggle-classes-with-delays/ but i cant seems to make it work.
Would appreciate any response, example. Thank you!
async and await
To avoid race conditions and ensure that each call to functions go in proper order (although order isn't that important with a method like toggleClass()), use async and await keywords with setTimeout().
Demo
$(window).load(openClose);
$('.callqueue').click(slideNav);
async function openClose() {
await new Promise((resolve, reject) => setTimeout(resolve, 3000));
var open = await slideNav();
await new Promise((resolve, reject) => setTimeout(resolve, 2000));
var close = await slideNav();
};
function slideNav() {
$('#dddnav').toggleClass('menu-open');
}
#man {
display: none;
}
#dddnav {
height: 30%;
background: #333;
position: fixed;
top: 0;
right: -270px;
width: 300px;
transition: right .5s;
-webkit-transition: right .5s;
}
#dddnav.menu-open {
right: 0;
transition: right .5s;
-webkit-transition: right .5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button class="callqueue"> CLICK </button>
<div id="dddnav" style="background: red; top: 10%;">
<img id="man" src="https://placehold.it/200" />
</div>
What about doing
$('.callqueue').click(function(){
$('#dddnav').toggleClass('menu-open');
$('body').toggleClass('menu-open');
});
// Let's define a callable to be used inside setTimeout.
toggleIt = function(){
$('#dddnav').toggleClass('menu-open')
};
$(window).load(function(){
setTimeout(
function(){
toggleIt()
setTimeout(toggleIt, 2000) // 5s as 3 + 2
}, 3000
)
})
#man {
display:none;
}
#dddnav {
height:30%;
background:#333;
position:fixed;
top:0;
right:-270px;
width:300px;
transition:right .5s;
-webkit-transition:right .5s;
}
#dddnav.menu-open {
right:0;
transition:right .5s;
-webkit-transition:right .5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button class="callqueue"> CLICK </button>
<div id="dddnav" style="background: red; top: 10%;">
<img id="man" src="http://placehold.it/200" />
</div>
Try this:
$(window).load(function (){
var start_time = new Date().getTime();
while (true) {
if(new Date().getTime() - startTime > 3000){
$('#dddnav').toggleClass('menu-open');
break;
}
}
});

Javascript - How to change animation's duration onclick

How can I change the animation duration onclick? This is what I've done, I created two buttons, one with an animationduration of 10s while the other has an animationduration of 20s. The duration regardless of which button I click is the same, 10 seconds, as it is in the class section. How can I get depending on the button I click two different durations? Please use normal Javascript, no Jquery. Thank you! I also need to use the document.GetElementById().classname =""; as it is in the code.
function tenseconds() {
animation();
var sd = document.getElementById('ghost').className = 'earth';
sd.style.animationDuration = "10s";
}
function twentyseconds() {
animation();
var sd = document.getElementById('ghost').className = 'earth';
sd.style.animationDuration = "20s";
}
function animation() {
document.getElementById('ghost').className = 'earth';
}
<!DOCTYPE html>
<html>
<head>
<style>
.earth {
position: relative;
animation: move 10s linear;
background: red;
height: 20px;
width: 20px;
}
#-webkit-keyframes move {
from {
left: 0%;
}
to {
left: 100%;
}
}
</style>
</head>
<body>
<div id="ghost"> </div>
<button onclick="tenseconds();">10 seconds </button>
<button onclick="twentyseconds()"> 20 seconds </button>
</body>
</html>
Updated to use an animation, data attributes etc. Customize as needed. NOT supported in Edge, IE perhaps others. Leave to you to investigate possible ways to fix that. Review OLD edit for the original "fix"
I added another element and button so you could see how it might be used.
var myAnimation = {
keyframes: [
// keyframes
{
transform: 'translateX(0px)'
},
{
transform: 'translateX(300px)'
}
],
options: {
// timing options
// ms of duration default 1 second
duration: 1000,
iterations: 1, //forever would be Infinity
easing: "linear"
}
};
function animation(target, duration, visual) {
let sd = document.getElementById(target);
sd.className = visual;
myAnimation.options.duration = duration * 1000;
sd.animate(myAnimation.keyframes, myAnimation.options,visual);
}
function setup() {
let classThings = document.getElementsByClassName("animate-button");
let myFunction = function() {
let duration = this.dataset.duration;
let visual = this.dataset.visual;
let target = this.dataset.target;
animation(target, duration, visual);
};
for (var i = 0; i < classThings.length; i++) {
classThings[i].addEventListener('click', myFunction, false);
}
}
(function() {
setup();
})();
<!DOCTYPE html>
<html>
<head>
<style>
.fire {
position: relative;
background: red;
height: 20px;
width: 20px;
}
.water {
position: relative;
background: blue;
height: 20px;
width: 20px;
}
</style>
</head>
<body>
<div id="ghost"></div>
<div id="billy"></div>
<button class="animate-button" data-duration="10" data-target="ghost" data-visual="fire">10 seconds</button>
<button class="animate-button" data-duration="20" data-target="ghost" data-visual="fire">20 seconds</button>
<button class="animate-button" data-duration="5" data-target="billy" data-visual="water">5 seconds billy</button>
</body>
</html>
I created a little function that takes the animation time in seconds as an argument. Read the comments in the code for explanation.
function animation(duration) {
// select whatever element you are trying to animate
let target = document.getElementById('ghost');
// change the animationduration before starting to animate
target.style.animationDuration = `${duration}s`;
// add the animating class and start the animation
target.classList.add('animating');
// create a timeout to remove the animating class from your animated element
setTimeout(() => {
target.classList.remove('animating');
}, `${duration*1000}`);
}
#ghost{
position: relative;
background: red;
height: 20px;
width: 20px;
}
.animating {
animation: move 10s linear;
}
#-webkit-keyframes move {
from {
left: 0%;
}
to {
left: 100%;
}
}
<!DOCTYPE html>
<div id="ghost"> </div>
<button onclick="animation(10);">10 seconds </button>
<button onclick="animation(20);"> 20 seconds </button>

Simon Game : Two colors in a row won't fade properly

I'm trying to build a javascript 'Simon says' game.
So far, I made some basic tests with buttons.
First button 'Start' generates a sequence. Second button 'Show' will show what was generated.
Everything works except when the same color, in the random generated sequence, appears in a row.
Ex: = [ 'blue', 'yellow', 'yellow']
Only in this case the fade-in / fade-out effect won't work.
I checked with DevTools, what was wrong and it seems that the loop adds the class 'fade-out' to both indexes (in the case above..to index 1 and 2).
Why is that? And how can I fix it?
HTML
<div id="container">
<div id="blue" class="btn"></div>
<div id="red" class="btn"></div>
<div id="yellow" class="btn"></div>
<div id="green" class="btn"></div>
</div>
<button id="startBtn">Start</button>
<button id='showMe'>Show</button>
CSS
.btn {
height: 100px;
width: 25vw;
border: 1px solid black;
opacity: 1;
transition: opacity 1s ease;
}
.fade-out {
opacity: 0.5;
transition: opacity 1s ease;
}
#container {
display: flex;
flex-wrap: nowrap;
}
#blue {
background-color: blue;
}
#yellow {
background-color: yellow;
}
#red {
background-color: red;
}
#green {
background-color: green;
}
JS
var color = container.querySelectorAll('div.btn');
var startBtn = document.getElementById('startBtn');
var showBtn = document.getElementById('showMe');
var pcSequence = [],
mySequence = [],
i,
theLoop;
startBtn.addEventListener('click', oneMore, false);
showBtn.addEventListener('click', showSeq, false);
function oneMore(){
pcSequence.push(color[Math.floor(Math.random() * 4)]);
}
function showSeq(){
i = 0;
theLoop = setInterval(function(){
if (i > 0){ pcSequence[i - 1].classList.remove('fade-out'); }
if (i >= pcSequence.length){
clearInterval(theLoop);
} else {
pcSequence[i].classList.add('fade-out');
}
i++;
}, 2000);
}
While I am not seeing the problem with fade-out appearing on two of the squares, I do see that, for example, in your case of blue, yellow, yellow, the yellow isn't doesn't become unfaded-out at all.
If that is the problem you are concerned about, the reason is that you are removing the class and then immediately re-adding it, so the ui is essentially not doing the fade-in.
Another strategy here might be to use the transitionend event to do the fade in, rather than doing that in the interval. Something like this (I put a hack in to force the red and yellow to be set each time):
var color = container.querySelectorAll('div.btn');
var startBtn = document.getElementById('startBtn');
var showBtn = document.getElementById('showMe');
var pcSequence = [],
mySequence = [],
i,
theLoop;
startBtn.addEventListener('click', oneMore, false);
showBtn.addEventListener('click', showSeq, false);
// Force red initially
pcSequence.push(color[1]);
function oneMore(){
// Force yellow each time they press Start
pcSequence.push(color[2]);
//Math.floor(Math.random() * 4)]);
}
function clearTransition() {
var colorSquare = pcSequence[i - 1];
colorSquare.removeEventListener('transitionend', clearTransition);
colorSquare.classList.remove('fade-out');
}
function showSeq(){
i = 0;
theLoop = setInterval(function(){
if (i >= pcSequence.length){
clearInterval(theLoop);
} else {
var colorSquare = pcSequence[i];
colorSquare.classList.add('fade-out');
colorSquare.addEventListener('transitionend', clearTransition);
}
i++;
}, 2000);
}
.btn {
height: 100px;
width: 25vw;
border: 1px solid black;
opacity: 1;
transition: opacity 1s ease;
}
.fade-out {
opacity: 0.5;
transition: opacity 1s ease;
}
#container {
display: flex;
flex-wrap: nowrap;
}
#blue {
background-color: blue;
}
#yellow {
background-color: yellow;
}
#red {
background-color: red;
}
#green {
background-color: green;
}
<div id="container">
<div id="blue" class="btn"></div>
<div id="red" class="btn"></div>
<div id="yellow" class="btn"></div>
<div id="green" class="btn"></div>
</div>
<button id="startBtn">Start</button>
<button id='showMe'>Show</button>

Vertical distribution of elements (and animation) - jQuery

I like to know the cleanest method to distribute elements vertically with jQuery. I nailed it but it's not very clean right >< ? I would like to get to do it without plugin... Thank you in advance ;-)
Here my JSFiddle
jQuery(document).ready(function($) {
var gap = 10;
var firstElem = $('#lorem');
if(firstElem.length){
var heightCall = (firstElem.offset().top)+(firstElem.outerHeight())+(gap);
var middleElem = $('#dolore');
middleElem.offset({top : heightCall});
var lastElem = $('#amet');
var NewHeightCall = (middleElem.offset().top)+(middleElem.outerHeight())+(gap);
lastElem.offset({top : NewHeightCall});
/* Animation */
$('#lorem, #dolore, #amet').hover(
function(){
$(this).stop().animate({left: (($(this).offset().left)-(20))+'px',opacity:'0.5'},'slow')
},
function(){
$(this).stop().animate({left: (($(this).offset().left)+(20))+'px',opacity:'1'},'slow')
});
}
});
I have fiddled around with your code:
This is a simplified version:
HTML:
<div id="lorem" class="vertical-block">My first ID div</div>
<div id="dolore" class="vertical-block">My second ID div.<br>My second ID div. My second ID div.</div>
<div id="amet" class="vertical-block">My third ID div</div>
CSS:
.vertical-block {
position: absolute;
padding:15px;
}
#lorem{
top:20%;
right:40px;
background:#f79673;
}
#dolore{
right:80px;
background:#cd7454;
}
#amet{
right:40px;
background:#a15338;
}
.vertical-block:hover {
opacity: 0.5;
padding-right: 30px;
-webkit-transition: all 2s;
transition: all 0.4s;
}
Javascript:
jQuery(document).ready(function($) {
var gap = 10;
var firstElem = $('#lorem');
var top = 0;
$('.vertical-block').each(function(element){
var $currentElement = $(this);
if (top === 0) {
top = $currentElement.offset().top + $currentElement.outerHeight() + gap;
} else {
$currentElement.offset({top: top});
top = top + $currentElement.outerHeight() + gap;
}
});
});
https://jsfiddle.net/rae2x4e0/1/
Now if you want to go for a purely css solution, then:
HTML:
<div class="container">
<div id="lorem" class="vertical-block">My first ID div</div>
<br />
<div id="dolore" class="vertical-block">My second ID div.<br>My second ID div. My second ID div.</div>
<br />
<div id="amet" class="vertical-block">My third ID div</div>
</div>
CSS:
.container {
position-relative;
text-align: right;
padding-top: 10%;
}
.vertical-block {
padding:15px;
display: inline-block;
margin-top: 20px;
}
#lorem{
right:40px;
background:#f79673;
}
#dolore{
right:80px;
background:#cd7454;
}
#amet{
right:40px;
background:#a15338;
}
.vertical-block:hover {
opacity: 0.5;
padding-right: 30px;
-webkit-transition: all 2s;
transition: all 0.4s;
}
https://jsfiddle.net/ycdwpjxw/1/

jQuery slide animate div with toggle button works every other time instead of every time

I'm trying to get a simple side navigation bar which you can hide and unhide with a single button.
So far I have it worknig but only every other click, so click to hide works, then does nothing, next click unhides, nothing etc. Yet I have to button set to an image to change on every click, and that is working.
What I have so far is....
HTML:
<div id="navBar-control">
<a href="#" id="toggle-slide-button">
<img src="http://i.imgur.com/8BMxPsC.png" width="50px" height="50px" />
</a>
</div>
<div id="navBar">
<div class="navBtn navBtnText">
Calculator
</div>
<div class="navBtn navBtnText">
About
</div>
<div class="navBtn navBtnText">
Other Services
</div>
</div>
Script:
var state = false;
$("#toggle-slide-button").click(function () {
if (!state) {
$('#navBar').animate({width: "toggle"}, 1000);
$('#toggle-slide-button img').attr('src', 'http://i.imgur.com/K3MG7gT.png');
state = true;
}
else {
$('#mnavBar').animate({width: "toggle"}, 1000);
$('#toggle-slide-button img').attr('src', 'http://i.imgur.com/8BMxPsC.png');
state = false;
}
});
and if it matters, CSS:
#navBar{
background-color: #660000;
height: 780x;
width: 80px;
}
.navBtn{
background-color: #660000;
color: white;
width: 80px;
height: 70px;
cursor: pointer;
border-bottom: 1px solid rgba(255,255,255,.2);
opacity: 1;
font-size: 12px;
text-align: center;
}
.navBtnText {
line-height: 120px;
vertical-align: bottom;
}
.navBtn:hover{
background-color:#990000;
}
#navBar-control {
width: 50px;
height: 100%;
padding: 0 15px;
background-color: #000;
}
Fiddle of this: http://jsfiddle.net/GUjPA/91/
I have been basing this off this fiddle: http://jsfiddle.net/GUjPA/13/ This has the desired behavior only that it is on the right of the screen instead of the left. The script I'm using is exactly the same, and besides different colours and size of side bar, its essentially exactly the same.
You have a mistake here:
$('#mnavBar').animate({width: "toggle"}, 1000);
must be
$('#navBar').animate({width: "toggle"}, 1000);
http://jsfiddle.net/GUjPA/94/ here works
var state = false;
$("#toggle-slide-button").click(function () {
if (!state) {
$('#navBar').animate({width: "toggle"}, 1000);
$('#toggle-slide-button img').attr('src', 'http://i.imgur.com/K3MG7gT.png');
state = true;
}
else {
$('#navBar').animate({width: "toggle"}, 1000);
$('#toggle-slide-button img').attr('src', 'http://i.imgur.com/8BMxPsC.png');
state = false;
}
});
try this: you had added an m to the second call to #navbar
simplified in fiddle

Categories

Resources