I'm trying to build a website locally using PHP and Javascript and MAMP.
What I'm looking for is to put a timer on every page of the website and that timer counts the time spent by the user in the whole website. Even if the user switches between pages the timer will still continue. The solution I've found only shows the time spent on each page and when I reload the same page again the timer restart from zero.
Here's the Javascript for the timer I did:
window.onload=function(){
time=0;
}
window.onbeforeunload=function(){
timeSite = new Date()-time;
window.localStorage['timeSite']=timeSite;
}
I've search everywhere for the solution but with no luck, if anyone knows how to do this please let me know.
Here's a working example. It will stop counting when the user closes the window/tab.
var timer;
var timerStart;
var timeSpentOnSite = getTimeSpentOnSite();
function getTimeSpentOnSite(){
timeSpentOnSite = parseInt(localStorage.getItem('timeSpentOnSite'));
timeSpentOnSite = isNaN(timeSpentOnSite) ? 0 : timeSpentOnSite;
return timeSpentOnSite;
}
function startCounting(){
timerStart = Date.now();
timer = setInterval(function(){
timeSpentOnSite = getTimeSpentOnSite()+(Date.now()-timerStart);
localStorage.setItem('timeSpentOnSite',timeSpentOnSite);
timerStart = parseInt(Date.now());
// Convert to seconds
console.log(parseInt(timeSpentOnSite/1000));
},1000);
}
startCounting();
Add the code below if you want to stop the timer when the window/tab is inactive:
var stopCountingWhenWindowIsInactive = true;
if( stopCountingWhenWindowIsInactive ){
if( typeof document.hidden !== "undefined" ){
var hidden = "hidden",
visibilityChange = "visibilitychange",
visibilityState = "visibilityState";
}else if ( typeof document.msHidden !== "undefined" ){
var hidden = "msHidden",
visibilityChange = "msvisibilitychange",
visibilityState = "msVisibilityState";
}
var documentIsHidden = document[hidden];
document.addEventListener(visibilityChange, function() {
if(documentIsHidden != document[hidden]) {
if( document[hidden] ){
// Window is inactive
clearInterval(timer);
}else{
// Window is active
startCounting();
}
documentIsHidden = document[hidden];
}
});
}
JSFiddle
Using localStorage may not be the best choice for what you need. But sessionStorage, and localStorage is most suitable. Have in mind that sessionStorage when opening a new tab resolves to a new session, so using localStorage has to do with the fact that if only sessionStorage was used and a user opened a new tab in parallel and visit your website would resolve to a new separate session for that browser tab and would count timeOnSite from start for it. In the following example it is tried for this to be avoid and count the exact timeOnSite.
The sessionStorage property allows you to access a session Storage
object for the current origin. sessionStorage is similar to
Window.localStorage, the only difference is while data stored in
localStorage has no expiration set, data stored in sessionStorage gets
cleared when the page session ends. A page session lasts for as long
as the browser is open and survives over page reloads and restores.
Opening a page in a new tab or window will cause a new session to be
initiated, which differs from how session cookies work.
function myTimer() {
if(!sessionStorage.getItem('firstVisitTime')) {
var myDate = Date.now();
if(!localStorage.getItem('timeOnSite')) {
sessionStorage.setItem('firstVisitTime',myDate);
} else {
if(localStorage.getItem('tabsCount') && parseInt(localStorage.getItem('tabsCount'))>1){
sessionStorage.setItem('firstVisitTime',myDate-parseInt(localStorage.getItem('timeOnSite')));
} else {
sessionStorage.setItem('firstVisitTime',myDate);
}
}
}
var myInterval = setInterval(function(){
var time = Date.now()-parseInt(sessionStorage.getItem('firstVisitTime'));
localStorage.setItem('timeOnSite',time);
document.getElementById("output").innerHTML = (time/1000)+' seconds have passed since first visit';
}, 1000);
return myInterval;
}
window.onbeforeunload=function() {
console.log('Document onbeforeunload state.');
clearInterval(timer);
};
window.onunload=function() {
var time = Date.now();
localStorage.setItem('timeLeftSite',time);
localStorage.setItem("tabsCount",parseInt(localStorage.getItem("tabsCount"))-1);
console.log('Document onunload state.');
};
if (document.readyState == "complete") {
if(localStorage.getItem("tabsCount")){
localStorage.setItem("tabsCount",parseInt(localStorage.getItem("tabsCount"))+1);
var timer = myTimer();
} else {
localStorage.setItem("tabsCount",1);
}
console.log("Document complete state.");
}
Working fiddle
If you want a server-side solution then set a $_SESSION['timeOnSite'] variable and update accordingly on each page navigation.
Related
I am pretty new to this whole jquery and javascript thing as I have really worked with server side languages. However, I have a challenge here where If the specific data received($status) is not the same with the one provided(queu or successf), the page should reload to fetch the data($status), and it should do this to a set number of time, if it reloads the page according to the number of time set; whether or not the data($status) is returned true, I want it to entirely stop reloading the page and exit.I have tried doing it this way; but I am not quite sure what I am missing.
$(document).ready(function($) {
var number_of_time_loaded = 7000;
var queue = '$status';
var inter;
if (queue == 'queu' || queue == 'successf') {
alert('successfully uploaded');
} else {
alert('kindly wait for some minutes');
for (;number_of_time_loaded < 70000;) {
inter = setInterval(function() {
window.location.reload(1);
}, number_of_time_loaded++);
if (number_of_time_loaded >= 21000) {
clearInterval(inter);
} else {
number_of_time_loaded++
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
So you checking a variable that is written by PHP. You are saying if this variable is not a certain value, you want the page to reload after a set period of time. Refreshing the page will reset the JavaScript variables so you would have to use local storage to keep the state.
var maxAttempts = 10;
var queue = "<?php echo $status; ?>";
if (queue == 'queu' || queue == 'successf') {
// it is updated
console.log("Updated);
sessionStorage.removeItem("attempts");
} else {
var currentAttempts = sessionStorage.getItem("attempts") || 0;
currentAttempts++;
if (currentAttempts < maxAttempts) {
console.log("waiting for another attempt");
sessionStorage.setItem("attempts", currentAttempts);
window.setTimeout(function () { window.location.reload(); }, 5000); // wait 5 seconds
} else {
// too many attempts made
console.log("too many attempts made");
sessionStorage.removeItem("attempts");
}
}
Better solution would be an Ajax request instead of refreshing the page. An
other option is setting meta refresh header in PHP and not having to use JavaScript.
So in the PHP if variable is not set, you echo out <meta http-equiv="refresh" content="5">
I'm creating a popup that will show when the user scrolls. However when the user clicks on the close button and refreshes the page and scrolls, I need to make a popup to show up after 10 minutes.
var popUp= document.getElementById("popup");
var closePopUp= document.getElementsByClassName('popup-close');
var halfScreen= document.body.offsetHeight/2;
var showOnce = true;
//show when scroll
window.onscroll = function(ev) {
if ((window.innerHeight+window.scrollY) >= halfScreen && showOnce) {
if(popUp.className === "hide"){
popUp.className = "";
}
showOnce = false;
}
};
//close button
for(var i = 0; i<closePopUp.length; i++){
closePopUp[i].addEventListener('click', function(event) {
if(popUp.className === ""){
popUp.className = "hide";
}
});
}
First you should detect whether the user has refreshed the page.You can achieve this using navigator object.Refer this question for implementation.
Secondly, once the user refreshes the page all the variables gets destroyed and initialized again.Hence you must use cookies or server side sessions to store whether user has already closed it once.But I always recommend you to setup sessions since cookies can be disabled by users.
To sum it up,setup an ajax request once the user refreshes the page,and if already he has closed the popup once, start a timeout for 10 minutes.
Adding a sample prototype for this :
var refreshed = false;
if (performance.navigation.type == 1) {
console.info( "This page is reloaded" );
refreshed = true;
} else {
console.info( "This page is not reloaded");
refreshed = false;
}
if(refreshed) {
//implement this ajax function yourself.
ajax('path/to/yourserver','method','data',function(response) {
if(response == "showed") {
var time = 10 * 60 * 1000;//10 minutes.
setTimeout(function() {
//show your popup.
},time);
}else {
//immediately show once scrolled.
}
});
}
You should use cookie for this and set cookie expiration time for 10 minutes take a look at this cookie plugin hope it helps
Set a cookie
$.cookie("example", "foo"); // Sample 1
$.cookie("example", "foo", { expires: 7 }); // Sample 2
Get a cookie
alert( $.cookie("example") );
Delete the cookie
$.removeCookie("example");
Or there is an example which is given in this answer take a look at this also
I am creating a chrome extension for auto refreshing a page after the specific interval provided by the user.
Based on the current tabs id it sets the interval and when user wishes to stop the interval he just clicks the stop button.
I am able to setInterval and store that timers value in object for eg :
javascript
var timerid = setInterval(function(){},interval)
var timers = {
timerid : timerid,
tabid : tabid
}
On Clearing Interval I just find the timer value by using the tab id
var timerid = _.findWhere(timers,{tabid : tabid });
clearInterval(timerid)
My Background.js
var tabId = 0;
var activeTabs = [];
var timers = [];
//listening for new tab message and refresh action
chrome.runtime.onMessage.addListener(
function(request, sender, response){
console.log("Inside background");
console.log("Tab Id ",request.tabId)
if(request.type === 'reload' && request.tabId !== null ){
console.log("Tab Reload Event")
console.log("Refreshing tab ",request.tabId );
var first = setInterval(function(){
chrome.tabs.reload(request.tabId);
},request.interval);
timers.push({ tabid: request.tabId,timerId : first });
console.log("Timers");
console.log(timers);
console.log("Done reloading")
}
if(request.type === 'clear' && request.tabId !== null){
console.log("running intervals");
console.log(timers);
var timer = _.findWhere(timers,{ tabid: request.tabId });
console.log("Clearing the running interval of ",timer.timerId);
console.log("Tab Id ",request.tabId);
clearInterval(timer.timerId);
}
}
)
chrome.tabs.onCreated.addListener(function(tab){
activeTabs.push(tab.id);
});
But this won't clear the interval i set previously ?
You appear to be re-declaring your timers object every time you start an interval.
You can also avoid having to use findWhere if you used the tabid as the property name.
var timerid = setInterval(function(){},interval)
var timers[tabid] = timerid;
Then to clear you can use:
var timerid = timers[tabid];
clearInterval(timerid);
The other problem you may be running into is if you are declaring your timer in a tab then that won't be shared with your other tabs. For that you will need to look at message passing, and using a background page to co-ordinate things.
Go for setTimeout method. just do some workaround in that like below.
isStopped = false;
interval = //userinput;
var operation = function(){
if(isStopped == true){
return;
}
......your code....
setTimeout(operation, interval);
}
Change the global varible isStopped to true when the user wants to stop.
Do recursive call after your code.
Let me know whether it works ?
I have a JS that plays a notification sound on the arrival of any new notifications. It works completely fine when a new notification comes, it should play the sound and it does play.
The notification I am talking about is only an integer which is returned from a query through an ajax call. I set this integer into my <asp:label.../> through the script.
The problem is : I have written the script on MasterPage. So every time I open a new page, or a refresh the same one the <asp:Label.../> gets cleared which I set from my script using .html(value) causing the script to run the sound again as every time the page refreshes or another page is loaded.
The problem may be is , that the value is not persistent ?
I want that the value should be set to the html of the label and also its value should be persistent on all the pages . What should I do for this persistence ?
My Script is :
myFunction();
function myFunction() {
$.get("AjaxServicesNoty.aspx", function (data) {
var recievedCount = parseInt(data);
alert(recievedCount);
var existingCount = $(".lblEventCount").text();
if (existingCount == "") {
existingCount = 0;
alert(existingCount);
} else {
existingCount = parseInt($(".lblEventCount").text());
alert(existingCount);
}
// if (existingCount == "" && recievedCount != 0) {
// $(".lblEventCount").html(recievedCount);
// $(".lblAcceptedCount").html(recievedCount);
// var sound = new Audio("Sound/notificationSound.wav");
// sound.play();
// }
if ((parseInt(recievedCount) > parseInt(existingCount)) && existingCount == 0) {
$(".lblEventCount").html(recievedCount);
$(".lblAcceptedCount").html(recievedCount);
var sound = new Audio("Sound/notificationSound.wav");
sound.play();
} else {
$(".lblEventCount").html(existingCount);
$(".lblAcceptedCount").html(existingCount);
}
});
}
setInterval(myFunction, 5000);
use DIV ID instead of selecting via class
$("#divID").html(existingCount);
I have an unusual problem. I'm using the following script to check for internet connection using navigator.onLine. If there is internet connection, the page will be refreshed every 15 seconds. If there isn't any internet connection, the page will use innerHTML to display a message.
<script type="text/javascript">
setInterval(function () {
if (navigator.onLine) {
var myInterval = setInterval(function(){window.location.href = "Tracker.html";},15000);
} else {
clearInterval(myInterval);
var changeMe = document.getElementById("change");
change.innerHTML = "<big><font face='Arial' color='#ffffff' size='2'><center>OFFLINE</big><br>No internet connection</font></center>";
}
}, 250);
</script>
My problem is, once there is no internet connection, the message will be displayed, BUT the page would still be refreshed one last time. I'm trying to avoid this, by using clearInterval(myInterval); in the else part of the code, however it won't work.
Any suggestions?
To refresh the page at 15 second intervals (provided that a connection is present), use:
function refresh() {
if(navigator.onLine)
window.location.href = "Tracker.html";
else{
var changeMe = document.getElementById("change");
change.innerHTML = "<big><font face='Arial' color='#ffffff' size='2'><center>OFFLINE</big><br>No internet connection</font></center>";
setTimeout(refresh, 250);
}
}
setTimeout(refresh, 15000);
At the end of 15 seconds, this checks whether a connection is present. If there is, it refreshes the page. If there isn't, it proceeds to check every 250 milliseconds afterwards until the user is reconnected, at which point it refreshes the page.
The net result is that the script refreshes the page as soon as possible after a minimum of 15 seconds have elapsed.
Here is a demonstration: http://jsfiddle.net/JGEt9/show
Whenever the outer interval callback is executed, a new myInterval variable is created and the previous one is lost (it goes out of scope because the callback terminates).
You have to persist the value of the variable between function calls by declaring it outside of the function. You also have to make sure that you are not creating another timeout if one is already running.
var timeout = null;
setInterval(function () {
if (navigator.onLine) {
if (timeout === null) {
timeout = setInterval(function(){window.location.href = "Tracker.html";},15000);
}
} else {
clearTimeout(timeout);
timeout = null;
// ...
}
}, 250);
You need to declare myInterval outside of the if statement. You should only need the refresh code once too. Something like this:
var myInterval = setTimeout(function(){window.location.href = "Tracker.html";},15000);
setInterval(function () {
if (!navigator.onLine) {
clearTimeout(myInterval);
var changeMe = document.getElementById("change");
changeMe.innerHTML = "<big><font face='Arial' color='#ffffff' size='2'><center>OFFLINE</big><br>No internet connection</font></center>";
}
}, 250);
Here you set the refresh interval and continually check to see if the browser is offline, and if it is, you remove the timer and do your cleanup code. I also changed the refresh code to use setTimeout instead of interval because it only happens once.
Another issue is you create changeMe but then try to use change. change doesn't exist. I fixed that in my example as well.
Note: This will not resume refreshing once connection is regained. See Felix Kling's answer.