I'm using proprietary software to create a page that I need to display (among other things, mainly HVAC controls) date and time. The software has a block for "custom html" (with the note "This content will be saved in a separate HTML file within <html> and <body> tags"), into which I place my code.
After some research (I'm not a coder and have mainly been copy-pasting), the code I have pasted into said block is as follows:
<script language="javascript">
var t = new Date();
document.write(t.toDateString()+""+t.getHours()+":"+t.getMinutes());
</script>
And this gets me pretty close to what I want (day, month, date, year, time). I'd prefer if I could get AM/PM but mainly what I want is for the date/time to auto-update so the user doesn't need to refresh the page before getting an accurate printout.
While I've seen many threads on this site devoted to auto-updating time/date, I'm not sure how to integrate any of them with the system I'm working with (I've been at this for some time now), so I thought I'd ask the question with the context I'm working with.
This is not the exact format you want, but gives different way to achieve what you need. with some string manipulation you can achieve the same. if you could share the exact format you want to display, I could modify the solution.
Using setTimeout() or setInterval() to continuously make changes to the user's screen often induces "layout thrashing", the browser version of cardiac arrest where it is forced to perform unnecessary reflows of the page before the user's screen is physically able to display the changes. This is very bad due to the taxing nature of page reflows, especially on mobile devices where the problem is most apparent, with junky page loads and battery drains.
It is for the above reasons requestAnimationFrame() was introduced. The method in a nutshell allows you to execute code on the next available screen repaint, taking the guess work out of getting in sync with the user's browser and hardware readiness to make changes to the screen. When we call requestAnimationFrame() repeatedly to create a screen update, we are assured that our update code is called when the user's computer is actually ready to make changes to the screen each time, resulting in a smoother, more efficient update. Furthermore, code called via requestAnimationFrame() and running inside background tabs in your browser are either paused or slowed down significantly (to 2 frames per second or less) automatically to further save user system resources- there's no point in running the screen update that isn't being seen.
(function updateTime() {
var time = (new Date()).toLocaleString({
hour12: true,
});
document.getElementById('current_time').innerHTML = time;
requestAnimationFrame(updateTime);
})();
<div id="current_time"></div>
setInterval(function(){
var t = new Date();
document.write(t.toDateString()+""+t.getHours()+":"+t.getMinutes());
}, 1000);
Will run your script once every second, unfortunately this doesn't get rid of old times, so I would suggest having a placeholder you can update like an html span element.
<span id="time"></span>
<script>
setInterval(function(){
var t = new Date();
document.getElementById("time").innerHTML =
(t.toDateString()+""+t.getHours()+":"+t.getMinutes());
}, 1000);
</script>
Now, your clock is going to need some formatting, because right now, if, say, the time is 11:05, it displays 11:5. I would check that out here
Hopefully this works in your system.
Related
I am making a browser game in html, css, and javascript, written in perl. Health and stamina are kept in the server and I use javascript to show the user a live updated count of these stats while the current page is loaded. This works fine, however if the user switches tabs or switches away from the browser and leaves it running in the background, the count value you see when you return does not keep up properly. So when you switch back to the browser, your counter might say 50/100 stamina when you actually have 100/100. So when you do something in the game (loads a new page) the server updates the counter to the true amount because the javascript is just keeping time to show the user a "live" rolling view in the browser.
Is there a way to ensure the javascript counter will continue to function even if the page/tab isn't active or on the forefront? Aside from completely re-writing my game to include continuous live server pushes in what is displayed on the browser to the user?
Say you are playing the game. You see your health and stamina regenerating. You switch to another program for a minute, then return to the game in the browser. You notice your health and stamina have not updated while you were away. But when you perform an action in the game, this value is updated to what it should be because it is tracked internally on the server. This is what I would like to fix. Hope that makes sense!
I have not tried anything to fix this issue yet besides searching the web and ending up on this site without a really "good" answer in sight, so I decided to ask the question.
Continuous server pushes wouldn't work either. Anything in the main event loop like a timer, or events happening when it's out of focus, gets slowed down by the browser to conserve resources. Some mobile browsers will stop it together.
The answer to the question is to change how your app keeps track of these stats.
Now some will say to use WebWorkers to run the timer in a separate thread but this won't solve all your issues. You'd still have a different version of the issue, like if someone restored your webpage from sleep or something along those lines. No background task can survive that.
You mention that you track these stats also on the server. That's convenient, so the most obvious thing you should do is detect when the tab comes back into focus using the Window focus event. You would then make all the calls to the server to fetch the most up-to-date stats and reset the timers based on that fresh data. To stop it from showing stale data while the request is in flight, you might choose to show a loading spinner or something during that period.
Another common way of fixing this is you keep around on each timer increment a var which says when the data last came back (a timestamp). When you leave focus, you detect this with the blur event and store that last timestamp somewhere. Then they come back into focus, you handle the focus event and calculate the difference between the current time and the last recorded time before defocus (blur). You may be able to recalculate from this period what the values should be.
But if your server has this info, it'd be far less error-prone and easy to just ask the server when they refocus.
I am doing research with an experiment using qualtrics and unfortunately I am completely new to coding. In my experiment a block of questions should be ended after a certain time (in this case 50 seconds). So far I have been using a solution (which I found here: https://research-it.wharton.upenn.edu/uncategorized/qualtrics-loop-merge-tips/) that appeared rather neat using a blank embedded variable "test_time", display logic and the following javascript code which I copied to every page of the block:
Qualtrics.SurveyEngine.addOnload(function()
{
var elapsed = Date.now() - Number("${e://Field/test_time}");
if (elapsed >= 50000){
Qualtrics.SurveyEngine.setEmbeddedData("test_time", 0);
}
});
However, in the exported data when summing up information from timing questions that I included, I see that people have extremely varying time they actually can spend on the questions of the block (from 30 to almost 50 seconds). I am guessing this is due to the fact that the script uses the time of the clock, irrespective of lag caused by a bad internet connection or slow browser.
However, for my project it is important that people actually have the same time for the task. I suspect I could use the information of the timing questions, but somehow I can't access them in Javascript. Another idea is to record the difference between the page appearing and the click on the next button.
I appreciated any of your ideas and inputs!
Use the built-in embedded variable Q_TotalDuration, which is the elapsed survey time in seconds. Set the start time of the block in the survey flow just before the block:
startBlock = ${e://Field/Q_TotalDuration}
Then your JavaScript becomes:
var elapsed = parseInt("${e://Field/Q_TotalDuration}") - parseInt("${e://Field/startBlock}");
if(elapsed >= 50) {
//do something here
}
I don't understand what happens when the time limit is reached and time_test is set to zero in your original code. It wouldn't have any impact on the current page. It seems like you should be setting up a timeout function to click the Next button when the time threshold is reached.
I'm developing a Chrome App (a.k.a. packaged app) where most of the work occurs in a textarea element, and I want to ensure that the user's work is automatically saved.
One impractical approach is to save the work in a file on every keystroke and other change to the textarea, with something like this:
$('#text').on("keypress paste cut change", function () {
// ... save to file
});
But that's way too much overhead, so instead I just set a dirty flag, and now the question is to effect the save at appropriate times if the dirty flag is set. These are some appropriate times I've come up with, all of which are easily implemented:
Every minute, which is the smallest interval that chrome.alarms.onAlarm will allow.
When the user exits the app with the Quit item on the File menu.
When the user explicitly chooses the Save item on the File menu. (This might go away in the final version, but it's very handy during development.)
The problem is that there is no event available when the user closes the app or the whole browser. These events do exist in JavaScript, but they are specifically disallowed in Chrome Apps. The rationale, as I understand it, is that the Chrome developers don't want to provide this crutch, and instead want to encourage app developers to implement apps that save work continuously. Fine! I'm all for it.
Any ideas how to implement autosaving in Chrome Apps?
Update: I just took a look at Gliffy Diagrams, perhaps the most ambitious of the Chrome Apps so far, and it doesn't do any saving when it's closed via the app window or from the dock. It only does it when Close or Save is chosen from its file menu. That's essentially what my app does.
You can use an normal JavaScript timer (say, 5 seconds) in the function where you're currently setting your dirty flag. Make the timer reset with each keypress, so that the autosave kicks in after 5 seconds of inactivity:
var inactiveTimer;
$('#text').on("keypress paste cut change", function () {
clearTimeout(inactiveTimer);
// save after 5 seconds, unless another keypress resets this timer
inactiveTimer = setTimeout(saveText, 5000);
}
Thus, you only save when the user hasn't done anything for 5 seconds, instead of saving after every single keystroke. Obviously, this doesn't handle the case that the user closes the app 4 seconds after he finishes typing, but it's better than your option #1.
I was curious if there was a way to detect the user pressing the "stop navigation" button in the browser using javascript (or, even better, jQuery.) For example, if you click a link for a webpage that takes a while to load, you may want to show a spinning loader. But what if the user cancels navigation to the page? Is there anyway to detect that to get rid of the spinning loader that you put?
EDIT: I did a bit more research, and there seems to be an onStop event in javascript but, wouldn't you know it, it only works in internet explorer. If anyone has any other ideas to implement a cross browser solution like onStop, that'd be wonderful, but if not, I'll answer my own question in a few days to close this.
EDIT 2: https://stackoverflow.com/a/16216193 says it's not possible. As do a few other answers.
Alright so, as promised, I'm going to answer my own question.
I've thought about this quite a bit - and I've come up with a solution. I wasn't able to make it work in code (I didn't try too hard), but it should work in theory.
So I thought about the criteria of deciding when a webpage should decide stop was called. I came up with this:
If the script hasn't died after a reasonable amount of time, it can be assumed navigation has been canceled.
Then a jQuery event can be fired on the body or something like that. But what constitutes "a resonable amount of time?" I figured it would be partially based on page render time (fetching images, etc.) to get an idea of how fast the user's internet is. That can be gotten by doing:
var start = new Date();
var time;
$("body").load(function () {
time = new Date() - start;
...
});
Multiply that by a coefficient (maybe 3 or something) and get an approxamate transfer time. (This would have to be adjusted to account for how long it would take for the server to generate the next page, dependent on how dynamic it is.) Then, using this new found time*3 you'd write something like this:
$("a").click(function() { //Anything that could go to another page should filter through here
setInterval(function() {$(document).trigger("navstopped");},time*3);
}
$(document).on("navstopped") {
//Do stuff now that we assume navigation stopped.
}
Assume. That's really all we're doing here. We may have an inconsistent internet connection, fast one minute, slow the next. Server load could be inconsistent too. Maybe it's serving up images like a ninja for this page, but it's hit with a bunch of requests the next, making it generate/serve the next page a bit slower. So we're just assuming that something interrupted the navigation some how, but we are not certain.
Now, of course, this could be used in conjunction with IE's onStop event, but this was really the only cross browser solution I could think of. I wasn't able to get it to work, but maybe some jQuery god may be able to in the future.
Edit before post: Even before I posted this, I had another idea. More browsers support onAbort. If we have a picture that never loads, and the user presses stop, will onAbort be fired? Even if another webpage is loading? It requires testing but that may work too. I like my first idea better though. Although unstable, it is more stable than this cockamamie idea and I realize this could be bad practice.
i need to run a function periodically regardless the page where i am. This function will get some data periodically.
I dont think that this works:
function myFunc()
{
//your code
}
//set the interval
setInterval(myFunc,2000) //this will run the function for every 2 sec.
Because it works only for the page where I am right now, so if i go to another page, function is not executed anymore.
I would like to write a function that start running when user is at index page and then is called periodically until user close the page.
Any idea? Thanks in advance!
That's not possible with javascript in the browser. When you navigate away from the page, the script will stop. You have to include a script on every page that initializes this periodical update. Or you could rewrite your application to a "single page application", which seems to be popular nowadays.
You'll need a backend application or cron-job to do that.
Another way do that would be to make an Ajax-only single page application. I guess twitter uses that model.
Depending on what your doing in the function you may be best to use a JS Worker which will run as a new thread and allow you to continue processing as much as you want in the background without having to worry about JS timeouts.
The main point here is what your asking for is near enough impossible within JS unless you use something similar to jQUery and dynamically load your pages in to a div? This would mean you still have the effect (visually) that you changing page but the browser only loads the data in.
Its very easy to in fact to load content in to a DIV using jQuery its:
$('#elementoloadid").load("/path/to/load");
You could achieve this without using jQuery but will take you longer.