I have 2 javascripts working but want to merge them into one.
The purpose of the script is to make a checkbox that changes the a varable for the refresh rate.
Script 1 (works as expected)
window.onload = function () {
var input = document.querySelector('input[type=checkbox]');
function check() {
if (input.checked) {
var timeout = "10000";
} else {
var timeout = "999999";
}
document.getElementById('result').innerHTML = 'result ' + timeout;
}
input.onchange = check;
check();
}
<input type="checkbox" value="1" />Checkbox
<br/>
<br/>
<span id="result"></span>
Script 2 (works as expected)
var timeout = 10000;
var action = function() {
$('#content').load('/arduino/refresh');
};
setInterval(action, timeout);
I tought I could just merge them together and let them live happily ever after so I created the following script: (it shows the checkbox but checking/unchecking does not change the refresh rate)
window.onload = function () {
var input = document.querySelector('input[type=checkbox]');
function check() {
if (input.checked) {
var timeout = "10000";
} else {
var timeout = "999999";
}
var action = function() {
$('#content').load('/arduino/refresh');
};
}
input.onchange = check;
check();
}
setInterval(action, timeout);
<input type="checkbox" value="1" />Checkbox
<br/>
<br/>
<span id="result"></span>
Any advise?
In the combined script, setInterval is not called within the check event handler. The local variable timeout is modified, but the new value is never used to actually change the refresh rate.
Also, use clearInterval and setInterval together when changing the refresh rate.
Related
So, I got an infinite loop to work in this function using setInterval attached to an onClick. Problem is, I can't stop it using clearInterval in an onClick. I think this is because when I attach a clearInterval to an onClick, it kills a specific interval and not the function altogether. Is there anything I can do to kill all intervals through an onClick?
Here's my .js file and the calls I'm making are
input type="button" value="generate" onClick="generation();
input type="button" value="Infinite Loop!" onclick="setInterval('generation()',1000);"
input type="button" value="Reset" onclick="clearInterval(generation(),80;" // This one here is giving me trouble.
setInterval returns a handle, you need that handle so you can clear it
easiest, create a var for the handle in your html head, then in your onclick use the var
// in the head
var intervalHandle = null;
// in the onclick to set
intervalHandle = setInterval(....
// in the onclick to clear
clearInterval(intervalHandle);
http://www.w3schools.com/jsref/met_win_clearinterval.asp
clearInterval is applied on the return value of setInterval, like this:
var interval = null;
theSecondButton.onclick = function() {
if (interval === null) {
interval = setInterval(generation, 1000);
}
}
theThirdButton.onclick = function () {
if (interval !== null) {
clearInterval(interval);
interval = null;
}
}
Have generation(); call setTimeout to itself instead of setInterval. That was you can use a bit if logic in the function to prevent it from running setTimeout quite easily.
var genTimer
var stopGen = 0
function generation() {
clearTimeout(genTimer) ///stop additional clicks from initiating more timers
. . .
if(!stopGen) {
genTimer = setTimeout(function(){generation()},1000)
}
}
}
Live demo
This is all you need!
<script type="text/javascript">
var foo = setInterval(timer, 1000);
function timer() {
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("demo").innerHTML = t;
}
$(document).on("click", "#stop_clock", function() {
clearInterval(foo);
$("#stop_clock").empty().append("Done!");
});
</script>
Why does this call my Action twice? For background, using .change only works when a user clicks somewhere else on the form. Also .change will not fire when the browser is closed. Hence the timer combined with the data-dirty property check. Thanks in advance.
var timeoutId;
$(function() {
var formElements = $('#myformid').find('input, select, textarea').add('[form=myformid]').not(':disabled').each(function() {
$(this).attr('data-dirty', false).on('input propertychange change', function() {
var changedText = $(this).val();
var commentID = $(this).attr('id');
clearTimeout(timeoutId);
timeoutId = setTimeout(function() {
// Runs 1 second (1000 ms) after the last change
// Saving to DB Here
$.post('#Url.Action("UpdateComment", "CommentJournal")', {
"ChangedText": changedText,
"commentID": commentID
});
$(this).attr('data-dirty', true);
}, 1000);
});
});
});
//Controller
[HttpPost]
[AllowAnonymous]
public ActionResult UpdateComment(string changedText, string commentID) {
return null;
}
Probably because both input and change events are being fired, with the change firing more than 1000ms after input fired, since change only fires when focus leaves the control. Example:
var timerId = 0;
$("#field1").on("input change", function(event) {
var type = event.type;
clearTimeout(timerId);
timerId = setTimeout(function() {
console.log("timeout fired for '" + type + "'");
}, 1000);
});
<p>Type something in the first field, wait at least a second, then tab out of the field:</p>
<div>
<label>
First field:
<input type="text" id="field1">
</label>
</div>
<div>
<label>
second field:
<input type="text" id="field2">
</label>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
If you hook input, there's no need to hook change.
This question already has answers here:
Incrementing value continuously on mouse hold
(5 answers)
Closed 5 years ago.
I have this script that adds 1 to a value every time I click on a button:
<script>
function incrementValue(id) {
var value = parseInt(document.getElementById(id).innerHTML);
value = value + 1;
document.getElementById(id).innerHTML = value;
}
</script>
<button onclick="incrementValue('skill_1')"> add </button><br>
<span id=skill_1>0</span>
However I want to adjust it so that if I hold down the mouse button, it'll repeat so I don't have to keep pressing it over and over.
Any way to do that using javascript? Or would jquery suit?
To achieve this you need to use the mousedown event to start a timeout (which is the delay before the incremental count starts) and an interval (which does the repeated counting). You'll also need a mouseup and mouseleave handler to remove both of those timers. Try this:
var timeout, interval;
[].forEach.call(document.querySelectorAll('.add'), function(button) {
button.addEventListener('mousedown', function() {
var id = button.dataset.target;
incrementValue(id);
timeout = setTimeout(function() {
interval = setInterval(function() {
incrementValue(id);
}, 50);
}, 300);
});
button.addEventListener('mouseup', clearTimers);
button.addEventListener('mouseleave', clearTimers);
function clearTimers() {
clearTimeout(timeout);
clearInterval(interval);
}
});
function incrementValue(id) {
var el = document.getElementById(id);
var value = parseInt(el.textContent, 10);
document.getElementById(id).textContent = ++value;
}
<button class="add" data-target="skill_1">add</button><br />
<span id="skill_1">0</span>
You'll need 3 event handler:
mousedown that will call a function, that will call itself with a timeout (continuosIncerment) while the mouse button is pressed.
mouseup that will clear the timeout when the button is released.
mouseleave that clears the timeout when the mouse leaves the button area.
const btn = document.querySelector('#btn');
const skill_1 = document.querySelector('#skill_1');
let value = 0;
let timer;
function continuosIncerment() {
skill_1.innerHTML = ++value;
timer = setTimeout(continuosIncerment, 200);
}
function timeoutClear() {
clearTimeout(timer);
}
btn.addEventListener('mousedown', continuosIncerment);
btn.addEventListener('mouseup', timeoutClear);
btn.addEventListener('mouseleave', timeoutClear);
<button id="btn"> add </button><br>
<span id="skill_1">0</span>
Instead of reading the value from the HTML, then writing it back, it's easier to hold the value in a variable, increment it, then write it out.
Did you know you can do this with a simple HTML spinner?
<input type="number" min="0" max="50" step="1">
I'd go with a solution like this: on mouse down event starts a repeating timer that triggers your function and it stops when the mouse up event occurs.
var inter = null;
function setInter(){
inter=setInterval(incrementValue, 500);
}
function unsetInter(){
clearInterval(inter);
}
function incrementValue() {
var value = parseInt(document.getElementById('skill_1').innerHTML);
value = value + 1;
document.getElementById('skill_1').innerHTML = value;
}
<button
onmousedown="setInter()"
onmouseup="unsetInter()"> add </button>
<br>
<span id=skill_1>0</span>
I wrote the function for check if button was clicked twice and if it was to measure the time between two clicks. It has to prevent multiple clicks in short time.
Button click:
$("#Save").click(function () {
dateTime1 = new Date().getTime();
BtnId = this.id;
showSaveDialog();
});
And measuring function:
ButtonWasTriggeredTwice: function () {
var result = false;
var currentTime = new Date().getTime();
var time = currentTime - dateTime1;
if (PreviousBtn === null) {
result= false;
} else {
if (PreviousBtn === BtnId) {
if ( time < 1500) {
result = true;
}
else result = false;
}
else {
result= false;
}
}
PreviousBtn = BtnId;
BtnId = null;
return result;
}
BtnId and PreviosusBtn are global scope variables.
The strange thing is this function works great when I set breakpoints in debugger. If I switch off debugger function blocks every next click on button, no matter what time interval is between clicks
You can use this solution with unbind and timeout, like this:
HTML
<input type="button" id="Save" value="save me" />
JS:
function saveEventButton(){
$("#Save").click(function () {
alert('saved!');
$("#Save").unbind('click');
setTimeout(function(){
saveEventButton();
}, 5000); // 5sec
});
}
saveEventButton();
This is the JSFiddle
UPDATE This solution is a mix from mine and Revish Patel solution
function disableTimeout(_this){
$(_this).prop('disabled','disabled');
setTimeout(function(){
$(_this).prop('disabled','');
}, 5000); // 5sec
}
$("#Save").click(function () {
alert('saved!');
disableTimeout(this);
});
This is the JSfiddle
You can also disable button when you first click is performed.
$(document).ready(function () {
$("#Save").click(function(){
$('#Save').prop('disabled','disabled');
// Perform your button click operation
});
});
I'm using the onChange attribute to flip a global variable to true. The page will then refresh if the global variable unfinished is false. If it's true, it should just show an alert. This works 90% of the time. On a few cases where the interval is at less than a minute, the unfinished variable will be ignored and the page will refresh anyway.
Is there a better and less hack-job way of achieving a way to block page refreshes? Basically it looks to me like onChange isn't firing if my interval is at less than 1 minute.
HTML
<textarea name="comment" id="thecommentbox" style="width: 100%;" onChange="blockRefresh();" class="thecommentbox form-control" style="height: 70px;" placeholder="Comment."></textarea>
JS
var unfinished = false;
function blockRefresh() {
unfinished = true;
document.getElementById('refreshBlocked').style.display = 'inline';
console.log('Refresh blocked.');
}
setTimeout(function(){
if(unfinished) {
alert("unfinished comment");
}
else {
window.location = window.location.pathname;
}
}, 600000); //ten minutes is 600,000
var timeRemaining = 600000;
var timer = setInterval('countdown()',60000);
function countdown() {
timeRemaining -= 60000;
document.getElementById('refreshTimer').innerHTML = "<strong>" + timeRemaining/60000 + "</strong>";
}
After some reading of this Textarea onchange detection and testing of the answers I think the best answer is to use a combination of the input and onpropertychange events.
In addition the user could press a key that doesn't actually change anything in the field you will need to get the value of the text field when the page first loads. When a change occurs compare the current value against that value.
(See code below)
var unfinished = false;
var textString = document.getElementById("thecommentbox").value;
function blockRefresh() {
if (textString != this.value) {
window.unfinished = true;
console.log('Refresh blocked.');
}
}
var txtBox = document.getElementById('thecommentbox');
if (txtBox.addEventListener) {
txtBox.addEventListener('input', blockRefresh, false);
} else if (txtBox.attachEvent) {
txtBox.attachEvent('onpropertychange', blockRefresh);
}
This will detect pasting from the context menu and work in IE in addition to most other browsers.
The onchange event isn't fired if your textarea field holds the focus. Use onkeyup instead to execute the blockRefresh function immidiately.
var unfinished = false;
var timer = setTimeout(function(){
if(window.unfinished) {
alert("unfinished comment");
}
else {
window.location = window.location.pathname;
}
}, 6000);
function blockRefresh() {
window.unfinished = true;
console.log('Refresh blocked.');
}