Javascript variable update on input - javascript

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>

Related

Change setInveral/Timeout speed dynamically with range input

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">

Manually set interval time for setInterval

I'm trying to create application where the user can select how often they want the counter to increment by. For example, they type into the input box that they want it to increment by 1 every 5 seconds, and the setInterval will be set to 5 seconds, etc. Here's what I have so far:
<input type="text" id="timer"></input>
<input type="button" onlick="setTime()" value="test" />
<h1>0</h1>
<button class="play">Play</button>
<button class="pause">Pause</button>
<script type="text/javascript">
function setTime() {
var output = $('h1');
var isPaused = true;
var count = 0;
timer = document.getElementById("timer").value;
setInterval(function() {
if(!isPaused) {
time++;
output.text(time);
}
}, timer*1000);
}
//with jquery
$('.pause').on('click', function(e) {
e.preventDefault();
isPaused = true;
});
$('.play').on('click', function(e) {
e.preventDefault();
isPaused = false;
});
</script>
Can I get any ideas or help? I appreciate it in advance
Refactoring a little your code, you can do it this way:
Every <input type="text" id="timer"></input>Seconds<br>
<button class="start">Start</button>
<h1>0</h1>
<button class="play">Play</button>
<button class="pause">Pause</button>
And the JS:
var interval = null;
var time = 0;
var output = $('h1');
function setTimer() {
var seconds = +($("#timer").val());//Get the user input (and convert to number)
interval = setInterval(function() {
time++;
output.text( time );
}, seconds*1000);
}
//with jquery
$('.pause').on('click', function(e) {
e.preventDefault();
if(interval){
clearInterval(interval);//Clear the created interval
}
});
$('.play').on('click', function(e) {
e.preventDefault();
setTimer();
});
$('.start').click(function(){
time = 0;
setTimer();
});
See the working example here: https://output.jsbin.com/cukehijuwo/
Each time the user calls setTime, you are creating another interval. These will continue to be created throughout the lifecycle of your application. You should remove timeouts before creating new ones:
var timeoutID = null;
function setTime() {
...
clearTimeout(timeoutID);
timeoutID = setTimeout(function() {
...
}, timer * 1000);
}
For reference: https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval
Full simple tested program, hope this will help you
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<script type="text/javascript">
function display() {
$("h1").html(parseInt($("#inc").val()) + parseInt($("h1").html())) ;
t = setTimeout("display()",parseInt($("#int").val())*1000)
}
function pauseT(){
clearTimeout(t);
}
function continueT(){
t = setTimeout("display()",parseInt($("#int").val())*1000)
}
</script>
Increment Value<input type="text" id="inc"></input>
Interval in Second<input type="text" id="int"></input>
<input type="button" onclick="display()" value="Start" />
<h1>0</h1>
<button onclick="continueT()">Continue</button>
<button onclick="pauseT()">Pause</button>

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