javascript - repeat action at regular interval after onlick has been triggered - javascript

I have a div which is displayed with onclick then which disappear with setTimeout:
css
#light {
position:absolute;
left:40px;
top:45px;
border-left:50px solid transparent;
border-right:50px solid transparent;
border-bottom:20px solid red;
opacity:0;
}
js (don't know if the syntax is correct but it works)
function change() {
var element = document.getElementById("light");
element.style.opacity = "1";
element.style.transitionDelay = "4s", // only the 1stime with onclick
setTimeout(() => {
element.style.opacity = "0";
}, 5000)
}
html
<button onclick="change()">light</button>
<div id="light"></div>
What I would like is that this action repeats then by itself every 2 minutes:
- after 2min, #light is displayed again for 5s (opacity="1")
- then hidden again (opacity="0")and so on, and so every 2 min.I know about the setInterval() method but it's too difficult for me to use it correctly - the script doesn't work at regular interval (every 2 min).ps: I've looked similar questions but all this is beyond my competence (ie, 0).

I'm not sure why you can't use timeouts?
Wouldn't something like this work?
( you can adjust the timers... I didn't want to wait minutes to see the light blink so I set it to few seconds)
let timer;
let started = false;
let delayTimer;
const lightOn = (clicked) => {
// do nothing if clicked for the second time
if (clicked && started) {return;}
const fn = () => {
const element = document.getElementById("light");
element.classList.add('light-on');
timer = setTimeout(lightOff, 1000);
};
if (clicked) {
delayTimer = setTimeout(fn, 3000);
} else {
fn();
}
started = true;
}
const lightOff = () => {
const element = document.getElementById("light");
element.classList.remove('light-on');
timer = setTimeout(lightOn, 2000);
}
const stop = () => {
clearTimeout(timer);
clearTimeout(delayTimer);
timer = undefined;
delayTimer = undefined;
started = false;
}
.light {
background-color: gray;
opacity: 0.1;
width: 2em;
height: 2em;
display: inline-block;
border: 1px solid black;
border-radius: 2em;
}
.light-on {
background-color: yellow;
opacity: 1;
}
<div id="light" class="light"></div>
<button onclick="lightOn(true)" style="display: block;">start</button>
<button onclick="stop()" style="display: block;">stop</button>

Related

How to set interval to always last Xs when clicked on carousel button (vanilla JavaScript)

I have made custom carousel (for learning) on this web page. Carousel has 2 buttons (next and previous) and dots (each dot is 1 picture). It all works fine, but there is one problem. I want to make automatic loop carousel (to loop through images in interval of X seconds). Now i am using setInterval(nextImgShow, 2000);. But every time i click on either button (next, previous, dots) the interval changes.
Example: I have interval of 2s. If i click on a button when 1,5s has passed, the next image will only show for 0,5s. If i click it right away at 0,5s, the next image will show for 1,5s.
I already try to fix this with clearInterval();, but it does not change a thing. I also try to use clearInterval(); and than set interval again setInterval(nextImgShow, 2000); (on every button), but no luck.
I also try to use setTimeout(); but again nothing.
My wish is: If interval is 2s, when i click on either of buttons, i want to reset/set my interval back to 2s. So that every image is displayed for 2s, no matter when the button was clicked.
Can anyone help me solve this?
Below is JavaScript code and link to my web page, so you can see.
LINK: Link to page, so you can see demo
// navigation selection
const navigation = document.querySelector("ul.navigation");
const navigationToggleButton = document.querySelector(".navigation-toggle");
const navigationList = document.querySelectorAll(".navigation a");
// background image selector
const backgroundImgDiv = document.querySelector(".bg");
const previousImgBtn = document.querySelector(".prev");
const nextImgBtn = document.querySelector(".next");
const imgDotBtn = Array.from(document.querySelectorAll(".dot"));
const arrImg = ['url("img/0.jpg")', 'url("img/1.jpg")', 'url("img/2.jpg")', 'url("img/3.jpg")'];
const dot0 = document.querySelector(".dot-0");
const dot1 = document.querySelector(".dot-1");
const dot2 = document.querySelector(".dot-2");
const dot3 = document.querySelector(".dot-3");
let startImgIndex = 0;
let currentIndex = 0;
// navigation functions
function toggleNav() {
navigation.classList.toggle("active");
}
function navLink() {
navigation.classList.remove("active");
}
// background image functions
function nextImgShow() {
startImgIndex++;
if (startImgIndex === arrImg.length) {
startImgIndex = 0;
}
currentIndex = startImgIndex;
backgroundImgDiv.style.backgroundImage = arrImg[startImgIndex];
toggleDotActive(currentIndex);
}
function previousImgShow() {
startImgIndex--;
if (startImgIndex === -1) {
startImgIndex = (arrImg.length - 1);
}
currentIndex = startImgIndex;
backgroundImgDiv.style.backgroundImage = arrImg[startImgIndex];
toggleDotActive(currentIndex);
}
function dotBtnNavigate() {
if (this.classList.contains("dot-0")) {
dotBtnSet(0);
} else if (this.classList.contains("dot-1")) {
dotBtnSet(1);
} else if (this.classList.contains("dot-2")) {
dotBtnSet(2);
} else if (this.classList.contains("dot-3")) {
dotBtnSet(3);
}
}
function dotBtnSet (number) {
backgroundImgDiv.style.backgroundImage = arrImg[number];
startImgIndex = number;
currentIndex = number;
toggleDotActive(currentIndex);
}
function toggleDotActive(currentIndex) {
switch(currentIndex) {
case 0:
dot0.classList.add("dot-active");
dot1.classList.remove("dot-active");
dot2.classList.remove("dot-active");
dot3.classList.remove("dot-active");
break;
case 1:
dot0.classList.remove("dot-active");
dot1.classList.add("dot-active");
dot2.classList.remove("dot-active");
dot3.classList.remove("dot-active");
break;
case 2:
dot0.classList.remove("dot-active");
dot1.classList.remove("dot-active");
dot2.classList.add("dot-active");
dot3.classList.remove("dot-active");
break;
case 3:
dot0.classList.remove("dot-active");
dot1.classList.remove("dot-active");
dot2.classList.remove("dot-active");
dot3.classList.add("dot-active");
break;
default:
break;
}
}
// navigation events
navigationToggleButton.addEventListener("click", toggleNav);
navigationList.forEach(item => item.addEventListener("click", navLink));
// background image event
nextImgBtn.addEventListener("click", nextImgShow)
previousImgBtn.addEventListener("click", previousImgShow);
imgDotBtn.forEach(btn => btn.addEventListener("click", dotBtnNavigate));
// for touch devices (carousel navigate)
const gestureZone = document.querySelector('.img-wrap');
let touchstartX = 0;
let touchstartY = 0;
let touchendX = 0;
let touchendY = 0;
// for touch devices function (carousel navigate)
function handleGesture() {
if (touchendX <= touchstartX) {
nextImgShow();
}
if (touchendX >= touchstartX) {
previousImgShow();
}
}
setInterval(nextImgShow, 2000);
// navigation events
navigationToggleButton.addEventListener("click", toggleNav);
navigationList.forEach(item => item.addEventListener("click", navLink));
// background image event
nextImgBtn.addEventListener("click", nextImgShow);
previousImgBtn.addEventListener("click", previousImgShow);
imgDotBtn.forEach(btn => btn.addEventListener("click", dotBtnNavigate));
// for touch devices events (carousel navigate)
gestureZone.addEventListener('touchstart', function(event) {
touchstartX = event.changedTouches[0].screenX;
touchstartY = event.changedTouches[0].screenY;
}, false);
gestureZone.addEventListener('touchend', function(event) {
touchendX = event.changedTouches[0].screenX;
touchendY = event.changedTouches[0].screenY;
handleGesture();
}, false);
You should be passing the interval ID (returned from setInterval) to the clear interval function. For example:
let myIntervalID = setInterval(nextImgShow, 2000);
Then you can clear the interval doing clearInterval(myIntervalID) just make sure the variable myIntervalID is in scope when you clear it.
Your clearInterval wasn't actually clearing the interval so you ran into this problem. Once you correctly clear the interval (like above) and call the interval again (kinda like resetting the interval) your image will show for the full interval
You should assign the setInterval to a variable and use clearInterval when the user clicks on one of the buttons to change the image and then set the interval again.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var change;
var i = 1;
var numOfImages = 3;
$(document).ready(function(){
document.getElementById("img1").classList.add("active");
change = setInterval(function(){
changeImage();
}, 2000);
});
function changeImage(){
var elem = document.getElementById("img"+i);
elem.style.display = "none";
i++;
if(i>numOfImages){
i = 1;
}
var elemToBeShown = "#img"+i;
$(elemToBeShown).show();
}
</script>
<style>
.images{
width: 50%;
margin-left: 40%;
}
#img2{
display: none;
}
#img3{
display: none;
}
.button{
border-radius: 50%;
height: 25px;
width: 25px;
margin: 0px 15px 15px 15px;
background-color: green;
display: inline-block;
}
.button:hover{
cursor: pointer;
background-color: blue;
}
</style>
</head>
<body>
<div class="images">
<img id="img1" src="data:image/jpeg;base64,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" width="125" height="125"/>
<img id="img2" src="data:image/jpeg;base64,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" width="125" height="125"/>
<img id="img3" src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRkoieaGln2U5aMZQZibEmbva3LVpVVOw-GbcizRKfmZzog4B5lnw" width="125" height="125"/>
</div>
<div style="width: 100%; text-align: center; margin-top: 25px;">
<div class="button" id="button1"></div>
<div class="button" id="button2"></div>
<div class="button" id="button3"></div>
</div>
<script>
$('.button').click(function(e){
var buttonid = $(this).attr('id');
var imgid = parseInt(buttonid.substring(6, buttonid.length), 10);
if(i!=imgid){
clearInterval(change);
document.getElementById("img"+i).style.display = "none";
document.getElementById("img"+imgid).style.display = "block";
i = imgid;
change = setInterval(function(){
changeImage();
}, 2000);
}
});
</script>
</body>
</html>

How to run pause and stop setInterval

My task:
Run setInterval loop when I hover the current block, for example #main
When I hover on some children element of #main, setInterval has to be paused
After when I leave children element of #main, and return my mouse focus back to #main, setTimeOut should run again. here is screen http://joxi.ru/L215V3qh65weW2
My code:
let num = 0;
var timer = function() { // auto click
{ num >= $(`.the_wrap_graf`).children().length-1 ? num = 0 : num++ }
$(`.year-wrap:eq(${num}) .q`).click()
}
var timerID = null // name of interval
$('.the_wrap_feed').hover(function (ev) { // hover run loop #main
timerID = setInterval(timer, 3000);
}, function (ev) { // mouseleave kill loop
clearInterval(timerID)
})
$(`.q`).mouseenter(function(e) { // kill loop when hover square
clearInterval(timerID)
})
If I add callback to $(.q), it breaks down. How can I do it?
You can't pause an interval timer. You can only cancel it and start a new one.
Re the requirement, I think I'd probably use mouseenter and mouseleave (which you're already doing, using hover) and track whether the cursor is in #main or a child:
var timer = 0;
var timerValue = 0;
var inMain = 0;
var inChild = 0;
function showTimer() {
$("#timer").text(
timer ? "Running: " + timerValue : "Not running"
);
}
function updateTimer() {
if (inMain && !inChild) {
if (!timer) {
timer = setInterval(tick, 100);
}
} else {
if (timer) {
clearInterval(timer);
timer = 0;
}
}
}
function tick() {
++timerValue;
showTimer();
}
showTimer();
$("#main")
.hover(
function() {
++inMain;
updateTimer();
},
function() {
--inMain;
updateTimer();
}
);
$("#main .child")
.hover(
function() {
++inChild;
updateTimer();
},
function() {
--inChild;
updateTimer();
}
);
#main {
border: 1px solid #aaa;
padding: 8px;
}
.child {
border: 1px solid #ddd;
margin: 8px;
}
<div id="timer"></div>
<div>
Not in main
<div id="main">
In main, not in any children
<div class="child">one child</div>
<div class="child">another child</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

requestAnimationFrame gives the wrong timestamp when showing a confirm dialog (Chromium?)

I have a simple animation, which is done using requestAnimationFrame (for demo purposes adapted from the example on MDN). If before the animation I show a confirm dialog, the timestamp received by the animation function is wrong. The difference between the first and second timestamps is equal to the time from the moment the confirm message was shown, until the "OK" button was clicked. This behaviour (bug?) is visible in Chrome and Opera (both running Chromium). Firefox and Internet Explorer 11 run as expected. Check the fiddle or the example below.
const cache = {
start: null,
target: null
};
function animate(timestamp) {
console.log(timestamp);
if (cache.start === null) {
cache.start = timestamp;
}
var progress = timestamp - cache.start;
cache.target.style.left = Math.min(progress / 10, 100) + 'px';
if (progress < 1000) {
requestAnimationFrame(animate);
} else {
cache.target.style.left = 0;
cache.start = null;
}
}
(function() {
const target = document.getElementsByTagName("div")[0];
cache.target = target;
const cb = document.getElementsByTagName("input")[0];
const btn = document.getElementsByTagName("button")[0];
btn.addEventListener("click", function() {
if (cb.checked) {
if (confirm("Just click 'OK' to start the animation, ok?")) {
requestAnimationFrame(animate);
}
} else {
requestAnimationFrame(animate);
}
})
})();
html,
body {
padding: 0;
margin: 0;
}
div {
width: 50px;
height: 50px;
border: 1px solid black;
background-color: yellowgreen;
position: absolute;
top: 50px;
}
button {
margin-top: 20px;
}
<button type="button">Start</button>
<label>
<input type="checkbox" />use "confirm"</label>
<div>
</div>
Open the console to see the received timestamps. The animation is set to run for 2 seconds. When showing the confirm dialog, if the "OK" button gets clicked faster than 2 seconds, the animation runs for the "remaining" time. If the time needed to click the "OK" button is longer than the time animation time, the element will not be animated and there will be 2 values (timestamps) sent to the console; the difference of these 2 values is the time needed to click the "OK" button.
I assume that this is a bug in Chromium. Is there a workaround for this (still animating with requestAnimationFrame, not trough CSS)? I couldn't find anything regarding this in their tracker. Does anybody have additional info on this?
I have to say, I found this very interesting.
After spending to much time on it I may have found a workaround for you. You can see that here. https://jsfiddle.net/qtj467n0/13/
The basic gist of it is, I replaced the DOMHighResTimeStamp that requestAnimationFrame provides with performance.now() which also returns a DOMHighResTimeStamp.
const cache = {
start: null,
target: null,
time: 2000
};
function animate(timestamp) {
console.log(timestamp);
if (cache.start === null) {
cache.start = timestamp;
}
var progress = timestamp - cache.start;
cache.target.style.left = Math.min(progress / 10, cache.time / 10) + 'px';
if (progress < cache.time) {
requestAnimationFrame(animate);
} else {
cache.target.style.left = 0;
cache.start = null;
}
}
const render = () => {
requestAnimationFrame((timestamp) => {
const performanceNow = performance.now();
animate(performanceNow)
});
}
(function() {
const target = document.getElementsByTagName("div")[0];
cache.target = target;
const cb = document.getElementsByTagName("input")[0];
const btn = document.getElementsByTagName("button")[0];
btn.addEventListener("click", function() {
if (cb.checked) {
const confirmed = confirm("Just click 'OK' to start the animation, ok?");
if (confirmed) {
render();
}
} else {
requestAnimationFrame(animate);
}
})
})();
html,
body {
padding: 0;
margin: 0;
}
div {
width: 50px;
height: 50px;
border: 1px solid black;
background-color: yellowgreen;
position: absolute;
top: 50px;
}
button {
margin-top: 20px;
}
<button type="button">Start</button>
<label>
<input type="checkbox" />use "confirm"</label>
<div>
</div>

Flash/blink tab effect in Javascript

I'm creating a simple chat in Javascript/PHP. I would like to flash/blink tab when new message is coming like on Facebook for example. How can I do that?
Here is example code:
(function () {
var original = document.title;
var timeout;
window.coders = function (newMsg, howManyTimes) {
function step() {
document.title = (document.title == original) ? newMsg : original;
if (--howManyTimes > 0) {
timeout = setTimeout(step, 1000);
};
};
howManyTimes = parseInt(howManyTimes);
if (isNaN(howManyTimes)) {
howManyTimes = 5;
};
cancelcoders(timeout);
step();
};
window.cancelcoders = function () {
clearTimeout(timeout);
document.title = original;
};
}());
You can use this code something like :
coders("New Message from Bhavin Solanki");
... or...
coders("New Message from Bhavin Solanki", 20); // toggles it 20 times.
You're better off doing the animation in css, and just using javascript to start and stop the animation. You got downvoted because you did not show your attempt at a solution.
(function(){
var message = document.querySelector('.message'),
button = document.querySelector('#button');
button.addEventListener('click', blink, false);
// this is where you toggle the class
function blink(e){
message.classList.toggle('blink');
}
})();
#keyframes blink {
from {
background-color: red;
color: white;
}
to {
background-color: white;
color: red;
}
}
.message {
text-align: center;
}
/* run the animation on .message when it also has the class .blink */
.message.blink {
animation: blink 1s linear infinite alternate;
}
<div class="message">You've got a message</div>
<button id="button">blink</button>

Stopwatch in seconds and milliseconds

Hi I'm working on a reaction test that checks how fast it takes for the user before they react, and I can't really find what I'm looking for. I was just wondering how to make a simple stopwatch in seconds and milliseconds so I can call the function later in HTML onclick.
Here is my code so far:
HTML
<input type="button" class="first" value="Call" onclick="call function" />
and that's pretty much it... I know HTML, CSS, JavaScript and a little bit jQuery.
Thanks in advance !
As a basic starting point you want to use setInterval to increment the stopwatch, with an additional function to toggle/reset it.
You can then either bind the click handler directly to the button (per below), or - I would tend to recommend you bind it in the Javascript itself (e.g. with .onclick=function(){....})
var s = 0,
ms = 0,
sEl = document.getElementById('s'),
msEl = document.getElementById('ms'),
play = false;
stopwatch = setInterval(function() {
if (!play) return;
if (ms === 99) {
s += 1;
ms = 0;
} else {
ms += 1;
}
update();
}, 1);
function update() {
sEl.innerText = s;
msEl.innerText = ms;
}
function toggle() {
if (!play) {
s = 0, ms = 0;
update();
}
play = !play;
}
body {
font-family: arial;
}
#s {
font-size: 50px;
}
#ms {
font-size: 30px;
display:inline-block;
width:35px;
}
button {
border: 1px solid grey;
background: lightgrey;
padding: 10px 40px;
}
<span id="s">0</span>s <span id="ms">00</span>ms
<br />
<button onclick="toggle();">Toggle</button>

Categories