I have an html file that accepts user inputs then uses Javascript to calculate a value based on those inputs. That result is then displayed in an input box after the program has finished.
What I'd like to do is make it so that when you click on the button to run the javascript, the input box that displays the result will show 'Calculating...' until the calculation finishes (the calculation can take ~5 seconds). However, if I put something like:
document.getElementById('answer').value = 'Calculating...';
at the very top of my Javascript code, it doesn't seem to update the input field whenever it runs. Instead, the program runs and then the result is finally updated in the input field.
Anyone know how I can update the input field when I run the program, then update it again with the result once the program finishes?
Thanks!
EDIT: Here's a better explanation of my code
<td colspan=1 align=left><input id="button" value="Calculate" onclick=calculate(this.form.type.value,this.form.d.value,this.form.c.value,this.form.freq.value)>
<input id="answer" readonly="true">
</td>
</tr>
function calculate(type,d,c,f) {
//Performs some calculation
document.getElementById('answer').value = TS;
}
That is because the event of re-drawing of the answer element doesn't happen until AFTER your JavaScript snippet is done (since the browser schedules these things in a queue).
What you need to do is to have your JavaScript interrupt the queue before the calculation starts:
Update the value to "Calculating" (puts the re-draw on the end of the queue)
Set a timer using setTimeout() for 0 seconds (with the timer launching the calculation code)
When the timer fires off immediately, it will put the call to the calculation code at the end of the queue, after the element re-draw.
<script>
document.getElementById('answer').value = 'Calculating...';
setTimeout( your_calculation(), 0);
</script>
This way, your JavaScript will set the field value, set up the timer and finish. Then next on the queue is the re-drawing of the answer element; and THEN the timer fires off and launches the calculation logic.
You have to use a timeout to allow the interface to refresh before doing the calculation.
document.getElementById('answer').value = 'Calculating...';
setTimeout( function() {
// TODO put your actual calculation statements/function calls here.
// document.getElementById('answer').value = answer;
}, 0 );
It sounds to me that you are setting a value on an element that may not exist on the page yet. Check for the DOM being ready first.
Tutorial: http://www.javascriptkit.com/dhtmltutors/domready.shtml
yean mean on the onclick event?
<script>
function onReady() {
document.getElementById('button').click = function() {
document.getElementById('answer').value = 'Calculating...';
document.getElementById('answer').value = doCalculation();
}
}
</script>
<body unload="onReady()">
Related
I have my set interval function and its working fine, but sometimes after setintervel trigged and I pressed Enter key some 4 to 5 times and my interval become infinite. can any one help me on this.
Thanks in advance.
code:
/one of the js file/
var intervaltime=setInterval(functionname(), 1000);
functionname()
{
if(pageloaded== "true"){ //pageloaded is coming from one JSP when I click that page.jsp
clearInterval(intervaltime);
}
}
**//page.jps**
<input type="hidden" value="true" id="pageloaded" name="pageloaded" />
page.jsp:
init method I added the hidden variable and to set the value of
First of all, the setInterval Method needs a function as first parameter, not "function()" .
For example :
setInterval(function() {
console.log("hello");
}, 1000);
You can also use the following syntaxe to declare your function ouside the timer :
function yourfunc() {
// ...
}
setInterval(yourfunc, 1000);
Also, I think that what you are trying to do is to stop something when your input is clicked or when your page is loaded. If so, the timer is not a good way to do that. You should use an event listener instead.
I hope it helped
HTML
<div id="backspace" ng-click="deleteString(''); decrementCursor();">
JS
<script>
$scope.deleteString = function() {
if($scope.cursorPosVal > 0){
//$scope.name = $scope.name - letter;
$scope.name = [$scope.name.slice(0, $scope.cursorPosVal - 1) + $scope.name.slice($scope.cursorPosVal)].join('');
console.log($scope.name);
setTimeout(function(){ setCaretPosition("inputBox", $scope.cursorPosVal); }, 30);
} else {
$scope.cursorPosVal = 1;
}
};
</script>
I am designing an on screen touchscreen keyboard. This is my backspace button. I am going to make it so that when you click and hold the backspace button, it starts removing characters automatically. I don't know where to begin with creating a setInterval, and I know a setInterval is exactly what I need to use here.
If I'm not wrong, you want that while you're keeping your button pressed, a function repeats itself.
You're right with setInterval(). However, the way you manage the event is wrong.
Take a look at this fiddle (It's not your code, but a simple example is the best way to understand):
http://jsfiddle.net/daq9atdd/1/
$(function(){
var interval = null;
$('#myButton').mousedown(function(){
interval = setInterval(function(){
console.log('Hello !');
}, 250);
});
$('#myButton').mouseup(function(){
clearInterval(interval);
});
});
I start the interval when the button is pressed, store it, and clear it when the button is released.
You’re so sure about setInterval.
If browser briefly hangs for whatever reason (say some background task), setInterval would go on queueing your backspace calls until it has some CPU time. This means user may see no change and hold backspace longer than needed, and then see a whole bunch of characters suddenly vanish when browser is back to normal.
Thus by setting a timeout after every call you’re making sure user won’t remove more characters than needed. Might be important if the goal is to improve UX.
Example implementation with AngularJS directives and setTimeout
See also:
setTimeout or setInterval?
noKid’s fiddle updated with setTimeout in mind
I am very new to javascript.
I am working a webgame. I am trying to use for loop to let players enter their names and select gamepiece by clicking. I'm struggling to make code to wait for user input (click on a game piece image) before moving on to the next player.
function GetPlayerNames(){
for (var i=1; i<=NumberPlayers; i++) {
ctxPlayers.fillStyle = "blue";
ctxPlayers.textAlign = "center";
var PlayerName = prompt("Name");
ctxPlayers.fillText (PlayerName + " Select Game Piece", cnvPlayers.width/2,cnvPlayers.height* (1/6));
// here i want to wait for a player to click on a game piece image
};
};
in vb.net version i used do while loop with application.doevents. It's my understanidng javascript doesn't have an equivalent, but i hope for a rather simple solution that will allow my to accomplish the same.
Thanks in advance.
The problem is that you're using prompt, which stops the execution of the script, and then you need to wait for a click, but there's no way to stop the execution for that like you can with prompt.
A better approach would be to check the values of all player names and images each time there is a change in a name or an image is clicked.
Will not give you any code for that, learn how you'd do it, it should be enough to get you started. So please don't use prompt combined with click listeners, but create an input field.
Here's a super simple example:
// keeping our input elements in a variable
var inputs = document.getElementsByTagName('input');
// loop over them to attach them a keyup listener
for(var i = 0; i < inputs.length; i++) {
inputs[i].addEventListener('keyup', checkNames);
}
// this function is called on each keyup event (and once in the beginning)
function checkNames() {
var playersReady = 0;
for(var i = 0; i < inputs.length; i++) {
if (inputs[i].value != "") {
playersReady++; // increment the value if the input is not empty
}
}
// output the message
document.getElementById('status').textContent = "Waiting for " +
(inputs.length - playersReady) + " more player" +
(inputs.length - playersReady == 1 ? "" : "s") + // this line is just for pluralizing
"..." +
(inputs.length - playersReady == 0 ? "The game can start now!" : "");
}
// initial call, just so we get the first status message
// without needing a keyup event first
checkNames();
<input type="text" placeholder="Player1 name" />
<input type="text" placeholder="Player2 name" />
<input type="text" placeholder="Player3 name" />
<p id="status"></p>
You can expand this example by adding images, and keeping track of how many of them are selected, similarly to how I keep track of non-empty player names.
Once you get comfortable with that, a bit more advanced task would be to try creating boxes for player names directly on canvas and listening for focus and keyboard inputs on them, but that's a whole another question...
Not required. When input occurs, the browser will call the JavaScript functions that you have attached to those events. Simply put, the browser has its own main loop that calls your code on a standardized set of conditions.
Let's say someone presses something on the keyboard. The browser will fire keydown and keyup events as the button is pressed and released. Also, if you use the statement window.requestAnimationFrame(yourFunction);, then yourFunction() will be called as early as possible in the next frame. If yourFunction() also calls window.requestAnimationFrame(yourFunction);, then yourFunction() will be your main loop.
In your case, most of your heavy code will be attached to the mousedown, mouseup, or click events. You should not need a main loop.
function yourClickHandler() {
//Whatever happens when your gamepiece is clicked.
}
/*
* This attaches the click event to some element that you use as your gamepiece.
* If you're using Canvas, you will attach it to the canvas (instead of #GamePiece
* and then need to figure out what is in the pixel that you clicked on in it.
*/
document.getElementById("#GamePiece").addEventListener("click", yourClickHandler, false);
Your game can just sleep between user clicks, unless you need complex animations and stuff that cannot be done with CSS transitions and so forth. If it's, say, a turn-based strategy, then you can just make the piece look clicked, then sleep, then give it a destination, then sleep, then select something else, then sleep. Etc.
If you do need complex animations and stuff...
Then it is best to have yourClickHandler() do as little as possible. Try to do nothing more than set a variable and return. Your requestAnimationFrame()-based draw/update functions should use those variables to perform the intense calculations then.
For instance, if you are making a character walk, let all the walking / falling / etc. happen once per frame. Just keep track of whether the button is pressed or not (or how far a joystick is tilted, etc.)
The reason for this is simple: Drawing happens once per frame, but input events might happen several times. You want to draw to the screen only once per draw to the monitor. Also, input events can happen at any time. You don't want a big calculation to happen a tenth of a millisecond before the frame is needed by the monitor. You want that to happen as early in the frame as possible.
This is a question related to Basic Javascript loading message while js processing completes
My main problem is that cursor not is changed before my two functions drawlegend() and display() are called, but changes after everthing has finnished.
With the code as below where the restore of the cursor temporary commented out, I get the hourglass, but after everything has finnished.
How to get my cursor to change to an hourglass before my slow functions are called?
examplefunc()
{
mini.append("text")
.text(series[i].name)
.attr("x",30)
.attr("y",(15+(15*i)))
.attr("stroke",(d3.rgb(192,192,192)))
.attr("fill",(d3.rgb(192,192,192)))
.attr("stroke-width",0)
.style("font-size","12px")
.attr("text-anchor","start")
.attr("id","legend")
.on('mouseup', legendclick);
}
//===== legend clicked
function legendclick()
{
//--- get mouse pos
var origin = d3.mouse(this);
//--- get channel
var ch=Math.floor((origin[1]-4)/15);
//--- toggle active state
if (series[ch].active==true)
series[ch].active=false;
else
series[ch].active=true;
setTimeout(setcursor("wait"),5);
drawlegend();
display();
//setTimeout(setcursor("default"),5); // temp removed to see any result at all
}
//===== set cursor
function setcursor(cursor)
{
d3.select("body").style("cursor", cursor);
}
It is known that executing things in javascript, hangs your application. This means that only the eventual output is displayed on your screen. Thus, when you change the cursor to "wait" and after execution to "cursor", the javascript hasn't changed it, because the ui thread was busy calculating the things in the functions "drawlegend" and "display". However, I think when you execute the "drawlegend" and "display" asynchronous like
setTimeout(function () {
drawLegend();
display();
setcursor("default");
}, 0);
then things should go like you want to.
Let me know if this works for you.
Extra info: on this slideshare (especially slide 5) is explained what your problem is.
Is there a way to check if a function has completed its operation using either javascript or jquery?
I'm trying to make a counter that slows down as the number gets bigger(decelerating the output, if you will), using setTimeout. As you know, the larger the number the longer the delay (in setTimeout).
What I'm trying to do is click a button, then current loop iteration is printed on the screen. This loop number is used as the setTimeout delay, so while the number is low it will quickly rush through, as it gets bigger the delay is larger thus making it print the number more slowly (since this number is the delay and the larger the delay the less often it prints it).
Here is the logic I'm trying to accomplish
1. Click button
2. Initiate loop
3. trigger function to set timeout
4. set timeout triggers a function to print the loop iteration #
5. Repeat step 3 until the number of set iterations is completed
Well, as you can see when the timeout is set the loop will continue, but there will be a timeout delay. Is there any way that I can put a pause-type function that waits until the timeout function is completed, and then continue onto the next iteration?
Here is my code
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<form>
<input type="button" value="Display alert box"
onclick="setMessage()" />
<script>
function setMessage(){
for(i=0;i<5000;i++){
var b = i;
timeMsg();
//some sort of puase here checking until timeMsg & docWrite are completed, then continue to the next iteration
}
}
function timeMsg(){
var t=setTimeout("docWrite()",b);
}
function docWrite(){
document.write(i);
}
</script>
</form>
</body>
</html>
Instead of doing this in a for loop, I would recommend doing something like the following:
function docWrite(i){
document.write(i);
}
function timeMsg(counter) {
var t;
counter++;
if (counter < 5000) {
t = setTimeout(function(counter){
docWrite(counter);
timeMsg(counter);
}, counter, counter)
}
}
timeMsg(0);