6

Say I've a browser extension which runs JS pages the user visits.

Is there an "outLoad" event or something of the like to start counting and see how long the user has spent on a page?

dsp_099
  • 5,021
  • 13
  • 59
  • 115
  • there is a way,you dont need a js for that..you can initiate a timer on pageload and keep on inserting values in your database.i will just give you a demo..wait 10 min – HIRA THAKUR Jul 23 '13 at 07:37
  • 2
    The best approach wouldn't be counting or running a timer, but to check the time onLoad and onBeforeUnload and calculate the difference. – Thor84no Jul 23 '13 at 07:42

7 Answers7

5

I am assuming that your user opens a tab, browses some webpage, then goes to another webpage, comes back to the first tab etc. You want to calculate exact time spent by the user. Also note that a user might open a webpage and keep it running but just go away. Come back an hour later and then once again access the page. You would not want to count the time that he is away from computer as time spent on the webpage. For this, following code does a docus check every 5 minutes. Thus, your actual time might be off by 5 minutes granularity but you can adjust the interval to check focus as per your needs. Also note that a user might just stare at a video for more than 5 minutes in which case the following code will not count that. You would have to run intelligent code that checks if there is a flash running or something.

Here is what I do in the content script (using jQuery):

$(window).on('unload', window_unfocused);
$(window).on("focus", window_focused);
$(window).on("blur", window_unfocused);
setInterval(focus_check, 300 * 1000);

var start_focus_time = undefined;
var last_user_interaction = undefined;

function focus_check() {
    if (start_focus_time != undefined) {
        var curr_time = new Date();
        //Lets just put it for 4.5 minutes                                                                                
    if((curr_time.getTime() - last_user_interaction.getTime()) > (270 * 1000)) {
            //No interaction in this tab for last 5 minutes. Probably idle.                                               
            window_unfocused();
        }
    }
}

function window_focused(eo) {
    last_user_interaction = new Date();
    if (start_focus_time == undefined) {
    start_focus_time = new Date();                                                               
    }
}

function window_unfocused(eo) {
    if (start_focus_time != undefined) {
    var stop_focus_time = new Date();
    var total_focus_time = stop_focus_time.getTime() - start_focus_time.getTime();
    start_focus_time = undefined;
    var message = {};
        message.type = "time_spent";
        message.domain = document.domain;
        message.time_spent = total_focus_time;
        chrome.extension.sendMessage("", message);
    }
}
Methos
  • 10,908
  • 11
  • 41
  • 47
3

onbeforeunload should fit your request. It fires right before page resources are being unloaded (page closed).

brezanac
  • 8,750
  • 4
  • 38
  • 57
2
<script type="text/javascript">

function send_data(){
            $.ajax({
                url:'something.php',
                type:'POST',
                data:{data to send},
                success:function(data){
                //get your time in response here
                }
            });
        }
//insert this data in your data base and notice your timestamp


 window.onload=function(){ send_data(); }
 window.onbeforeunload=function(){ send_data(); }

</script>

Now calculate the difference in your time.you will get the time spent by user on a page.

John Dvorak
  • 24,891
  • 12
  • 64
  • 80
HIRA THAKUR
  • 15,044
  • 14
  • 47
  • 82
  • `setInterval` does not guarantee that your function will be called exactly `` amount of time apart, it does a best effort attempt. Really you'd want to check the time, not assume that it's been exactly the amount of time you're expecting. – Thor84no Jul 23 '13 at 07:44
  • understood,will modify my answer – HIRA THAKUR Jul 23 '13 at 07:45
  • I'm concerned with hammering my server with requests - isn't that what it's doing? – dsp_099 Jul 23 '13 at 07:50
  • 1
    @MESSIAH That looks a lot better except you need to make it `window.onbeforeunload` instead of `window.onbeforeload`. – Thor84no Jul 23 '13 at 07:57
  • @Thor84no I've gone ahead and assumed it was a typo – John Dvorak Jul 23 '13 at 08:12
2

For those interested, I've put some work into a small JavaScript library that times how long a user interacts with a web page. It has the added benefit of more accurately (not perfectly, though) tracking how long a user is actually interacting with the page. It ignore times that a user switches to different tabs, goes idle, minimizes the browser, etc.

Edit: I have updated the example to include the current API usage.

http://timemejs.com

An example of its usage:

Include in your page:

<script src="http://timemejs.com/timeme.min.js"></script>
<script type="text/javascript">
TimeMe.initialize({
    currentPageName: "home-page", // page name
    idleTimeoutInSeconds: 15 // time before user considered idle
});
</script>

If you want to report the times yourself to your backend:

xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","ENTER_URL_HERE",true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var timeSpentOnPage = TimeMe.getTimeOnCurrentPageInSeconds();
xmlhttp.send(timeSpentOnPage);

TimeMe.js also supports sending timing data via websockets, so you don't have to try to force a full http request into the document.onbeforeunload event.

jason.zissman
  • 2,602
  • 1
  • 16
  • 22
1

The start_time is when the user first request the page and you get the end_time by firing an ajax notification to the server just before the user quits the page :

window.onbeforeunload = function () {
  // Ajax request to record the page leaving event.
  $.ajax({ 
         url: "im_leaving.aspx", cache: false
  });
};

also you have to keep the user session alive for users who stays long time on the same page (keep_alive.aspxcan be an empty page) :

var iconn = self.setInterval(
  function () { 
    $.ajax({ 
         url: "keep_alive.aspx", cache: false }); 
    }
    ,300000
);

then, you can additionally get the time spent on the site, by checking (each time the user leaves a page) if he's navigating to an external page/domain.

Chtiwi Malek
  • 9,757
  • 1
  • 66
  • 65
  • Yes, it is cross-browser. the $.ajax here uses jquery, but it can be done with only javascript : http://stackoverflow.com/questions/8567114/how-to-make-an-ajax-call-without-jquery – Chtiwi Malek Jul 23 '13 at 08:05
  • 1
    I meant, window.onbeforeunload. I checked at mozilla dev and it looks you are correct. Works for me. – dsp_099 Jul 23 '13 at 08:10
0

Revisiting this question, I know this wouldn't be much help in a Chrome Ext env, but you could just open a websock that does nothing but ping every 1 second and then when the user quits, you know to a precision of 1 second how long they've spent on the site as the connection will die which you can escape however you want.

dsp_099
  • 5,021
  • 13
  • 59
  • 115
0

Try out active-timeout.js. It uses the Visibility API to check when the user has switched to another tab or has minimized the browser window.

With it, you can set up a counter that runs until a predicate function returns a falsy value:

ActiveTimeout.count(function (time) {
    // `time` holds the active time passed up to this point.
    return true; // runs indefinitely
});
dodov
  • 4,065
  • 3
  • 25
  • 44