Change setInveral/Timeout speed dynamically with range input - javascript

I wonder if it's possible to change setInterval or setTimeout speed dynamically with html5 range input? If so how do I do that? I've tried to save value from input to a variable and then set the variable as an Interval/Timeout time but It didn't work and the Interval/Timeout worked full speed on change.
Can anyone give me some examples, please? :)
var elem = document.querySelector('input[type="range"]');
var rangeValue = function(){
var newValue = elem.value;
var b = newValue;
delay = b;
setInterval(function(){
console.log("Hi")
}, delay);
}
elem.addEventListener("input", rangeValue);
<input name="1" type="range" min="1000" max="7000" step="10" value="0">

The input event is going to fire multiple times for the range input as it is slid, so when you think you are only setting 1 interval/timeout you are setting multiple. This gives the impression that your timer is running at fullspeed (which I assume you mean as if it was set to 0 delay).
What you can do to counter act that is save the timer id that is returned from setTimeout/Interval. Then immediately clear it at the beginning of the callback to make sure any previous timers are no longer running.
var elem = document.querySelector('input[type="range"]');
var timerId = null;
var rangeValue = function(){
clearInterval(timerId);
var delay = elem.value;
timerId = setInterval(function(){
console.log("Hi")
}, delay);
}
elem.addEventListener("input", rangeValue);
<input name="1" type="range" min="1000" max="7000" step="10" value="0">

You need to add two different things. First you need to store the current interval so you can clear it when a new one is set. Also you should add a timeout when the slider is changed so that you're not setting the interval at every value along the path.
var elem = document.querySelector('input[type="range"]');
var slideInput;
var currentInterval;
var rangeValue = function(){
if (currentInterval) {
clearInterval(currentInterval);
}
var newValue = elem.value;
var b = newValue;
delay = b;
currentInterval = setInterval(function(){
console.log("Hi")
}, delay);
}
elem.addEventListener("input", function()
{
if (slideInput) {
clearTimeout(slideInput);
}
slideInput = setTimeout(rangeValue, 250);
});
<input name="1" type="range" min="1000" max="7000" step="10" value="0">

Related

settimeout using a variable input

I want to create a setTimeout with the timeout amount being input by the user.
e.g. I want the user to be able to delay the playback of an audio sample by manually inputting the delay time into a box.
Is it possible to trigger setTimeout from variable input or am I going about this the wrong way?
Yes, you can do this by collecting the number and using it as the timeout variable.
<input type="number" id="timeout">
Then you can collect it with .value
var timeout = +document.querySelector("#timeout").value;
setTimeout(my_function(), timeout);
Remember this is the number of milliseconds, so to make it into seconds multiply timeout by 1000.
var timeout = +document.querySelector("#timeout").value;
// convert from milliseconds to seconds
setTimeout(my_function(), timeout * 1000);
Here is a complete example with seconds.
function timeout() {
var milliseconds = +document.querySelector("#timeout").value;
var seconds = milliseconds*1000;
setTimeout(() => {
alert("Timeout has ended");
}, seconds);
}
<input type="number" id="timeout" value="1">
<button onclick="timeout()">Submit</button>
const delay = parseInt(window.prompt("number in millisecond"));
setTimeout(() => {
window.alert("Its took me " + delay + " millisecond to show up");
}, delay);
I wish this is what are you looking for
By using an <input> element you can have the user set a value for a delay. Then when you want to call the setTimeout, use the value of that input as the delay.
const fire = document.getElementById('fire');
const delay = document.getElementById('delay');
fire.addEventListener('click', () => {
const duration = Number(delay.value);
setTimeout(() => {
alert(`hello after ${duration}ms`);
}, duration);
});
<label for="delay">Set the delay</label>
<input type="number" id="delay" value="500">
<button type="button" id="fire">Fire</button>
Here is the Demo Code.
HTML:
<form>
<input type="number" name="delayTime"/>
<button>Submit Time Delay</button>
</form>
Javascript:
const form = document.querySelector("form");
form.addEventListener("submit",(e)=>{
e.preventDefault();
setTimeout(()=>{
document.querySelector(".audio").play()
},parseInt(`${form["delayTime"]000`}));
});
NOTE: You will need to give time as seconds, I have simply added 3 zeros to make it seconds.

Javascript variable update on input

I have a function where I'm trying to update one parameter based on the value of a range input
a.start = function () {
var t = 50;
var rangeInput = document.getElementById('speed');
rangeInput.addEventListener("change", function () {
t = document.rangeInput.value;});
setInterval(function () {
a.update();
a.draw();
}, t );
};
And honestly I'm getting frustrated, because I can't get this function to work dynamically. It somehow works simply with
a.start = function () {
var t = document.getElementById('speed');
setInterval(function () {
a.update();
a.draw();
}, t );
};
but only after I refresh the page. Honestly, my understanding of javascript is rather poor, I know it can be done using AJAX, but do I have to do it for such a simple thing? Any tips appreciated. HEre's html:
<form>
<label for="speed">
<input id="speed" type="range" name="points" min="10" max="2000" >Animation speed</label>
</form>
You need to cancel any running timer before you start a new one with a new time associated with it. Also, your code needs to be separated a bit.
// Place all this code at the bottom of the code, just before the </body>
var rangeInput = document.getElementById('speed');
var t = 500; // Default
var timer = null; // Reference to the interval timer
rangeInput.addEventListener("change", function(){
t = rangeInput.value;
// Cancel any previous timers
clearInterval(timer);
// Do the animation every t milliseconds
timer = setInterval(function(){
// Commented out only because we don't know what "a" is:
//a.update();
//a.draw();
// For debugging:
console.log(t);
}, t);
});
<form>
<label for="speed">
<input id="speed" type="range" name="points" min="10" max="5000" >Animation speed</label>
</form>
You could also do this using setTimeout() instead of setInterval():
// Place all this code at the bottom of the code, just before the </body>
var rangeInput = document.getElementById('speed');
var t = 500; // Default
var timer = null; // Reference to the interval timer
rangeInput.addEventListener("change", animate);
function animate(){
clearTimeout(timer);
t = rangeInput.value;
// Commented out only because we don't know what "a" is:
//a.update();
//a.draw();
// For debugging:
console.log(t);
// Do the animation every t milliseconds. Call the function recursively
timer = setTimeout(animate, t);
}
<form>
<label for="speed">
<input id="speed" type="range" name="points" min="10" max="5000" >Animation speed</label>
</form>

Change setInterval value dynamically

I want to change interval value of setInterval dynamically. I'm struggling due to presence of a loop in setInterval callback function. I have seen too many questions on stackoverflow. But there is no any solution which can help me. If anyone know answer then please explain with an example. Thank You.
Here is my code.
<html>
<head>
<script type="text/javascript">
var speed = 10;
function updateSlider(slideAmount) {
speed = slideAmount;
}
function load() {
downloadUrl("points.xml", function (data) {
/* code */
abc();
});
function abc() {
function track() {
/* code */
downloadUrl("points.xml", function (data) {
var xml = data.responseXML;
var points = xml.documentElement.getElementsByTagName("point");
var i = 0;
setInterval(function () {
if (i != points.length) {
alert(speed);
}
i++;
}, 100 * speed);
});
}
track();
}
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest;
request.onreadystatechange = function () {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.setRequestHeader("Content-type", "text/xml");
request.send(null);
}
function doNothing() {
}
</script>
</head>
<body onload="load();">
<div id="slider">
5% <input id="slide" type="range" min="1" max="20" step="5" value="10" onchange="updateSlider(this.value)" /> 200%
</div>
<div id="chosen">10</div>
</body>
The trick is to not use setInterval, and to use setTimeout in a loop instead.
setInterval reads the timing value you give it once, schedules based on this timing, and forgets about it. The only thing you can do is clearInterval(myInterval) if you've assigned your interval to a variable like myInterval.
setTimeout is much the same, except we can use it to manually loop on the same function. Manually looping allows us to change the timing of setTimeout after each timeout.
Here's a quick example. Moving the slider to the left makes the ticking faster, and to the right, slower.
DEMO
var timing = 250,
i = 0,
output = document.getElementById('output');
function loop() {
i++;
output.innerHTML = i;
window.setTimeout(loop, timing);
}
document.querySelector('input[type="range"]').addEventListener('change', function (e) {
timing = parseInt(this.value);
});
loop();
<input type="range" min="100" max="500" value="250" />
<div id="output"></div>
As a side note: Using this pattern is almost always a better option than using setInterval. setInterval runs the chance that your function execution could take longer than the duration of the interval. This never happens with a looping setTimeout if you call setTimeout last in the function.
Documentation:
WindowTimers.setInterval
WindowTimers.setTimeout
This is a version without setInterval i always use:
function timer()
{
var timer = {
running: false,
iv: 5000,
timeout: false,
cb : function(){},
start : function(cb,iv,sd){
var elm = this;
clearInterval(this.timeout);
this.running = true;
if(cb) this.cb = cb;
if(iv) this.iv = iv;
if(sd) elm.execute(elm);
this.timeout = setTimeout(function(){elm.execute(elm)}, this.iv);
},
execute : function(e){
if(!e.running) return false;
e.cb();
e.start();
},
stop : function(){
this.running = false;
},
set_interval : function(iv){
clearInterval(this.timeout);
this.start(false, iv);
}
};
return timer;
}
Usage:
var timer_1 = new timer();
timer_1.start(function(){
//magic here
}, 2000, false);
var timer_2 = new timer();
timer_2.start(function(){
//more magic here
}, 3000, true);
//change the interval
timer_2.set_interval(4000);
//stop the timer
timer_1.stop();
The last parameter of the start function is a boolean if the function needs to be run at 0.
You can also find the script here: https://github.com/Atticweb/smart-interval
Here's another easy way to dynamically update interval.
var intv_sec = 1500; // Initial interval in milliseconds
var speed = 1.5; // Multiplier
function chk_fn(){
// Your code here
console.log(intv_sec);
// Reset and update interval
clearInterval(chkh);
intv_sec = intv_sec*speed;
chkh = setInterval(chk_fn, intv_sec);
}
var chkh = setInterval(chk_fn, intv_sec);

Disable a button for 30 seconds

I have a button (where I can't change any of the HMTL) that clicks to save an answer to a question.
I want to disable this button for 30 seconds so that they cannot answer the question unless 30 seconds has passed. I don't know much javascript but I was told this can be used to do this.
Here is the html code that I cant change in any way:
<input type="submit" class="btnLarge" value="Submit" name="submit">
I thought maybe I can use the getElementByClassName but I'm not sure how that will be called. Can anyone help?
Starts with your button disabled, Notice added disabled attribute
HTML
<input type="submit" class="btnLarge" value="Submit" name="submit" disabled>
JavaScript
If you can't change HTML
document.getElementsByName("submit")[0].disabled = true;
To enable after 30 seconds
Here use setTimeout, to enable it after 30 seconds. In the anonymus function of setTimeout.
To identify element you can use document.getElementsByName, it returns a list of elements with a given name in the (X)HTML document. Thus to access first element [0] is used
Modify the DOM property is also called disabled and is a boolean that takes true or false.
setTimeout(function(){
var element = document.getElementsByName("submit")[0] ;
element.disabled = false;
}, 30000);
Complete Code
window.onload = function(){
document.getElementsByName("submit")[0].disabled = true;
setTimeout(function(){
var element = document.getElementsByName("submit")[0] ;
element.disabled = false;
}, 30000);
}
Try this
<script type="text/javascript">
setTimeout (function(){
document.getElementById('submitButton').disabled = null;
},30000);
var countdownNum = 30;
incTimer();
function incTimer(){
setTimeout (function(){
if(countdownNum != 0){
countdownNum--;
document.getElementById('timeLeft').innerHTML = 'Time left: ' + countdownNum + ' seconds';
incTimer();
} else {
document.getElementById('timeLeft').innerHTML = 'Ready!';
}
},1000);
}
</script>
<form>
<input type="submit" disabled="disabled" id="submitButton" />
<p id="timeLeft">Time Left: 30 seconds</p>
</form>
You could try something like this:
var element = document.getElementById('submitBtn');
element.disabled = true;
setTimeout(function(){
element.disabled = false;
}, 30000);
I would create a re-usable function that takes the specified amount of time and the className as inputs.
function disableElementForSpecifiedTime(className, disabledTime_milliseconds)
{
var element = document.getElementsByClassName(className)[0];
element.disabled = true;
setTimeout(function(){
element.disabled = false;
}, disabledTime_milliseconds);
}
Call it like this
disableElementForSpecifiedTime("btnLarge", 3000)
In the name of usability I would recommend highlighting the button when it's enabled, perhaps by making it bigger for a moment, using a jquery animation.
try this
in javasript
var i=0;
document.getElementsByName('submit')[0].setAttribute("disabled","disabled");
window.onload = function() {
window.setTimeout(setdis, 30000);
}
function setdis() {
if(i==0)
{
document.getElementsByName('submit')[0].disabled = false;
i++;
}
}
good luck
Add the attributes disabled and id="submit-form" to your button.
window.setTimeout(setEnabled, 30000);
function setEnabled() {
var submitButton = document.getElementById('submit-form');
if (submitButton) {
submitButton.disabled = false;
}
}
<input type="submit" class="btnLarge" value="Submit" name="submit" id="submit-form" disabled>
As you can't change the html, you can use javascript functions. Give an id to your button.
Make it disabled on page load.
<input type="submit" class="btnLarge" value="Submit" name="submit" disabled="disabled" id="saveAns">
Then you can use a timer function to enable it after 30 seconds
<script type="text/javascript">
window.onload=function() { setTimeout(function()
{
document.getElementById('saveAns').disabled = false;},30000);
}

How to get clearInterval to work with a button using Javascript/jQuery (not a variable/interval ID issue)

Trying to implement clearInterval to stop the continuous display of user-inputted strings.
This isn't an interval ID issue, as I have defined the setInterval function as a variable already (and still not working):
oldHandle = setInterval(function () {
But I'm trying to link the clearInterval function to a button, so that when it's pressed, the display will stop looping thru the user inputted strings.
Fiddle
HTML:
<h1 id='output'></h1>
<title>FORM</title>
<form id="frm">
<input id="txt" type="text" placeholder="Type something tasty..." name="text">
<label>1 at a time:
<input id='autoListen' type="checkbox" name="autoListen">
</label>
<input id='submitBtn' type="submit" value="OK">
<input type="button" value="Stop" onclick="stopDisplay()">
<div class="controlbox">
<div class="controlpanel"></div>
</div>
</form>
JS:
$(document).ready(function () {
var txtBox = $('#txt');
var frm = $('#frm');
var output = $('#output');
var subBtn = $('#submitBtn');
var container = [];
var oldHandle;
frm.submit(function (event) {
event.preventDefault();
var result = txtBox.val();
var $entry = $("<p>" + result + "</p>");
container.push(result);
$(".controlpanel").append($entry);
var i = 0;
clearInterval(oldHandle);
oldHandle = setInterval(function () {
if (i >= container.length) {
i = 0;
}
if (container.length > 0) {
output.text(container[i]);
console.log(container[i]);
++i;
} else {
output.empty();
clearInterval(oldHandle);
}
}, 2500)
txtBox.val('');
});
$('#autoListen').click(function () {
if ($('#autoListen').is(':checked')) {
subBtn.hide();
output.text(txtBox.val());
txtBox.keyup(function () {
output.text(txtBox.val());
})
} else {
subBtn.show();
txtBox.unbind('keyup');
}
});
$(".controlbox").on('dblclick', 'p', function() {
var $entry = $(this);
container.splice($entry.index(), 1);
$entry.remove();
});
function stopDisplay(){
clearInterval(oldHandle);
};
});
Any ideas as to where I'm going wrong??? Is this a scope issue? Am I defining the clearInterval function in an improper place? Or maybe my button isn't set up properly? I tried following clearInterval examples I found, to no avail...
Note: The Stop button can be found on Line 10 of HTML, the setInterval function on Line 20 of JS, and the stopDisplay/clearInterval function on line 60 of JS
Also: feel free to try out the interface - type in multiple strings, they'll display and re-display on constant loop. I'm trying to get them to stop looping thru the display upon the click of the stop button...
The problem is that the stopDisplay function is defined within an anonymous function, not in the global scope. So it's not accessible to inline Javascript in the onclick attribute.
The best fix is to bind the click handler with jQuery rather than the onclick attribute. Give it an ID:
<input id="stop" type="button" value="Stop">
and in your jQuery do:
$("#stop").click(stopDisplay);
Try removing the line:
var oldHandle;
I believe that will solve your scope issue and get you on the right track.

Categories

Resources