I have a map with multiple cities on it. I also have a loop showing the details of each city. I would like to completely stop the loop once I click on one of the cities.
I tried with: clearTimeout(loopIdx) but it didn't work. Could you please help me?! Cheers.
LOOP:
$(function() {
var $mapCol = $('.map-col');
var $mapBtn = $('.map-btn');
var $mapLoops = $('.map-loop');
var $btnLoops = $('.btn-loop');
loopIdx = (function _loop(idx) {
$mapCol.removeClass('active-map');
$mapBtn.removeClass('active-btn');
$mapLoops.removeClass('active-map').eq(idx).addClass('active-map');
$btnLoops.removeClass('active-btn').eq(idx).addClass('active-btn');
setTimeout(function() {
_loop((idx + 1) % $mapLoops.length);
}, 6000);
}(0));
});
BTN:
<div class="btn-loop">City</div>
Assign the result of setInterval() to a variable, and use that in the clearTimeout() call.
$(function() {
var $mapCol = $('.map-col');
var $mapBtn = $('.map-btn');
var $mapLoops = $('.map-loop');
var $btnLoops = $('.btn-loop');
var timer;
loopIdx = (function _loop(idx) {
$mapCol.removeClass('active-map');
$mapBtn.removeClass('active-btn');
$mapLoops.removeClass('active-map').eq(idx).addClass('active-map');
$btnLoops.removeClass('active-btn').eq(idx).addClass('active-btn');
timer = setTimeout(function() {
_loop((idx + 1) % $mapLoops.length);
}, 2000);
}(0));
$btnLoops.click(function() {
clearTimeout(timer);
});
});
.map-loop.active-map {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="btn-loop">City</div>
<div class="map-loop">1</div>
<div class="map-loop">2</div>
<div class="map-loop">3</div>
<div class="map-loop">4</div>
<div class="map-loop">5</div>
<div class="map-loop">6</div>
<div class="map-loop">7</div>
You need to access the timeoutID by name or identifier to clear it. (See https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearTimeout.)
If you want loopIdx to be the identifier, you can use something like:
let needToClear = false;
let loopIdx = setTimeout(function(){}, 6000);
// ...state changes here...
if(needToClear){ clearTimeout(loopIdx); }
Related
let timer = document.querySelector("#timer");
var counter = 3;
function myFn() {
counter--
if (counter === -1) {
counter = 3
}
timer.innerText = counter
}
btn.onclick = function() {
text.innerHTML += 'clicked' + '<br>'
}
var myTimer = setInterval(myFn, 1000);
<div id="timer"></div>
<button id="btn">Button</button>
<div id="text"></div>
I'm trying with this small code to read the div#timer every second and check for a click condition in console.log() F12. It gives me different error in every way I try to do it.
let timer = document.querySelector("#timer");
let btn = document.querySelector("#btn");
setInterval(() => {
console.log(timer.textContent)
if (timer.textContent === '0') {
btn.click()
}
}, 1000);
Consider the following jQuery example.
$(function() {
var timer = 0;
var counter = 3;
var timeObj = $("#timer");
var btnObj = $("#btn");
var txtObj = $("#text");
var interval;
function myFn() {
if (--counter >= 0) {
txtObj.append("Clicked<br />");
} else {
clearInterval(interval);
}
}
interval = setInterval(function() {
timeObj.html(++timer);
}, 1000);
btnObj.click(myFn);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="timer">0</div>
<button id="btn">Button</button>
<div id="text"></div>
You will want to use setInterval() and not setTimeout().
The setInterval() method, offered on the Window and Worker interfaces, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.
This method returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval().
See more: https://developer.mozilla.org/en-US/docs/Web/API/setInterval
Using the -- and ++ before the variable will also apply the change before it is used.
The decrement operator (--) decrements (subtracts one from) its operand and returns the value before or after the decrement, depending on where the operator is placed.
Adjusting the logic here can also ensure that the button click does allow the user to keep performing actions.
I've reviewed the other clearInterval posts here for a clue as to why my code isn't functioning as intended. Despite my best efforts, I still can't get clearInterval to stop my count.
I'm trying to do something simple: have a count, increase by one until the stop button is pushed.
I have tried different, and incorrect variables, but I cannot find a working solution.
<p>Count Up:</p>
<p id="count">1</p>
<button onclick="clearInterval(current)">Stop</button>
<script>
var current = 1;
function animateValue(id) {
var obj = document.getElementById(id);
var current = parseInt(obj.innerHTML);
setInterval(function () {
current++;
obj.innerHTML = current;
}, 1000);
}
animateValue("count");
</script>
Store the value returned by setInterval in a variable and pass that as the parameter to clearInterval instead of counter:
<p>Count Up:</p>
<p id="count">1</p>
<button onclick="clearInterval(interval)">Stop</button>
<script>
var interval;
var current = 1;
function animateValue(id) {
var obj = document.getElementById(id);
var current = parseInt(obj.innerHTML);
interval = setInterval(function () {
current++;
obj.innerHTML = current;
}, 1000);
}
animateValue("count");
</script>
I want to make a common function that can be call in html so I can update the value from variable.
function getActivityPoint(activityName) {
document.getElementsByClassName('share_points')[0].innerHTML = activityName;
}
my variable
var ap = {
'movie_review':'20',
}
And in HTML I would like to do this.
<div class="share_points" onload="getActivityPoint(ap.movie_review)">-</div>
<div class="share_points" onload="getActivityPoint(ap.game_review)">-</div>
.............
The inline onload event does not work for a div.
You may change your code in order to change your divs, using data attributes, like:
<div class="share_points" data-load="movie_review">-</div>
and on window load you can do your work:
window.addEventListener("load", function(event) {
document.querySelectorAll('.share_points').forEach(ele => getActivityPoint(ele, ap[ele.dataset.load]));
});
function getActivityPoint(ele, activityName) {
ele.textContent = activityName;
}
var ap = {
'movie_review':'20',
'game_review': 10
}
/****************
For Compatibility issue you may write:
window.addEventListener("load", function (event) {
Array.prototype.slice.call(document.querySelectorAll('.share_points')).forEach(function (ele) {
getActivityPoint(ele, ap[ele.dataset.load]);
});
});
For IE < 9 the solution is:
window.addEventListener("load", function (event) {
var divs = document.querySelectorAll('.share_points');
for (i = 0; i < divs.length; i++) {
getActivityPoint(divs[i], ap[divs[i].dataset.load]);
}
});
*/
<div class="share_points" data-load="movie_review">-</div>
<div class="share_points" data-load="game_review">-</div>
You can do:
var ap = {
'movie_review': '20',
'game_review': '100'
},
share_points = document.getElementsByClassName('share_points');
window.addEventListener('load', function() {
Array.prototype.forEach.call(share_points, function(el) {
el.innerHTML = ap[el.dataset.review];
});
});
<div class="share_points" data-review="movie_review">-</div>
<div class="share_points" data-review="game_review">-</div>
Have 2 objects on one, need to make both of them getting classes:
<script>
$(document).ready(function(){
var delayMillis = 200;
$('#overtop').hover(function(){ $('#honemove').addClass('hover');}, function () { setTimeout(function() { $('#honemove').removeClass('hover'); }, delayMillis); });
$('#overtop').hover(function(){ setTimeout(function() { $('#htwomove').addClass('hover'); }, delayMillis); }, function () { $('#htwomove').removeClass('hover'); });
});
</script>
<div id="overtop" class="overlay"></div>
<h1 id="honemove" class="h1a"><span>TITLE OF THE TITLE</span></h1>
<h2 id="htwomove"><span>INFO BELLOW TITLE</span></h2>
It works currently, but it glitches if u do a lot of mouse hovers, the CSS part is fine, I guess it doesn't like having two separate scripts on one action.
Use clearTimeout to prevent any sort of race condition from occurring:
$(document).ready(function() {
var $overtop = $('#overtop')
var $honemove = $('#honemove')
var $htwomove = $('#htwomove')
var delay = 200
var token
$overtop.hover(function() {
clearTimeout(token)
$honemove.addClass('hover')
token = setTimeout(function() {
$htwomove.addClass('hover')
}, delay)
}, function() {
clearTimeout(token)
$htwomove.removeClass('hover')
token = setTimeout(function() {
$honemove.removeClass('hover')
}, delay)
})
});
.hover {
color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="overtop" class="overlay">Overlay</div>
<h1 id="honemove" class="h1a"><span>TITLE OF THE TITLE</span></h1>
<h2 id="htwomove"><span>INFO BELLOW TITLE</span></h2>
I'm making a list filter and want a delay in case the user is a fast typer. Looking at different solutions for similar questions hasn't helped me and I don't understand the logic they implement.
This is my current code:
$.fn.filterList = function(){
var inputFilter = $(this);
var list = $('#' + inputFilter.data('list'));
var listItems = list.children('li');
inputFilter.keyup(function(){
setTimeout(function () {
var term = inputFilter.val().toLowerCase();
listItems.each(function(i, e){
var city = ($(e).text()).toLowerCase();
if(city.startsWith(term)){
console.log(city);
}
});
}, 800);
});
};
$('.my-input').filterList();
The problem with this is that it will trigger on each keyup, no matter how fast the user types.
How can I implement a delay so that it does not trigger for each keyup?
On each successive keypress you need to clear the previous timer so that the function only fires X milliseconds after typing ends. Try this:
var timer;
inputFilter.keyup(function() {
clearTimeout(timer);
timer = setTimeout(function() {
var term = inputFilter.val().toLowerCase();
listItems.each(function(i, e) {
var city = $(e).text().toLowerCase();
if (city.startsWith(term)) {
console.log(city);
}
});
}, 800);
});
Here's a simplified working example:
var timer;
$('#foo').keypress(function() {
clearTimeout(timer);
timer = setTimeout(function() {
$('div').fadeIn('fast').delay(1000).fadeOut('fast');
}, 800);
});
div { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="foo" />
<div>You stopped typing 1 second ago</div>
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
inputFilter.keyup(function() {
delay(function(){
var term = inputFilter.val().toLowerCase();
listItems.each(function(i, e){
var city = ($(e).text()).toLowerCase();
if(city.startsWith(term)){
console.log(city);
}
});
}, 800 );
});
try the following code:
Html:
<input type="text" id="inputtext" />
Jquery code:
<script type="text/javascript">
$(document).ready(function () {
$('#inputtext').keyup(function () {
setTimeout(function () {
alert("Hi");
}, 5000);
});
});
</script>
On each keyup count clicks and after some of them trigger function.
Pro-tip: And use
.on('keyup', function(){}).