Detect when a user leaves a website - javascript

I am trying to create my own website access library (for fun) like Google Analytics where I can detect when a user accesses my website, what pages they view etc.
Is there a way to determine when the user leaves a page &/or leaves the website for good?
I have successfully coded (in python) the detecting when the user 1st accesses my site (using a cookie) & how to determine what pages they view. But I don't know how I could detect when they user leaves the website for good?
Is there a way in javascript (maybe I can detect when the page/url is changing?). I know in HTTP there is a referrer header that tells me where the user came from, maybe when the user moves to another website (outside of mine), I can be notified of this (because I will be the referrer in that HTTP request)? Am I correct?

Using jquery you can trigger this:
$(window).bind('beforeunload', function() {
// ajax call perhaps
// triggering a write to db or filesystem...
});
Pure javascript way:
<html>
<head>
<script>
function closeIt()
{
return "Any string value here forces a dialog box to \n" +
"appear before closing the window.";
}
window.onbeforeunload = closeIt;
</script>
</head>
<body>
<a href="http://www.somewhere.com">Click here to navigate to
www.somewhere.com</a>
</body>
</html>

As long the user plays by the rules you expect the onbeforeunload will work. That means, closing a tab, or closing the window, or navigating to another site.
However, you have no way to detect this reliably with javascript, onbeforeunload doens't fire in many cases, such as shutting down the browser (ctrl+q), browser crash, history (back) and opera and some versions of chrome have limited support to onbeforeunload.
If you want to detect it with high precision, you must send Ajax requests periodically that shows the user is "still alive". register those requests in a database or file and analyze it by the time sequence.
So, if you "ping" the database every 20 seconds you can know from pretty simple queries that the browser hasn't "pinged" after a short while, and determine the user is no longer in the site.

You can mark all links on your site as inner or outer links. They must point to your site, but then redirect to location, selected by user. Before redirection you can point that user left away from your site.
But.
I'd better putted on every page on your site a little script which (say every 20-30 sec) make a GET request to specific url on your site. So you can track number of each user requests.

There is an unload event you can handle in JavaScript. For example:
window.onunload = unloadPage;
function unloadPage()
{
alert("unload event detected!");
}
Unfortunately, there is no way to tell where the user is actually going when they leave the current page (unlike a referrer, when you enter the page).
One idea is, to set a variable (perhaps in database) in the unload handler (via AJAX call or what not), and then remove it if user enters another page shortly after that. Whichever record is not removed (or deactivated - soft deletes) is your last exit event before the user actually bounced off your web site or closed the browser.

You can bind to the window.beforeunload or window.unload.
Neither of these methods are very reliable though.

Related

Triggering multiple individual JavaScript functions via URL without a page refresh

I'm building a simple webapp using NFC(near field communication), which involved certain tags being programmed with the URL of my website + a hash that will trigger a specific JavaScript function.
For example, "www.website.com/index.html#hide/one" will hide the element labeled "one" on the webpage. Simple enough, right? I thought it would be.
I've since learned that when you tap an NFC tag, it opens the URL in a new webpage/tab. I think this could be averted if my webpage checked to see if there are any other open pages and closes them, though.
If there's a better way to do this(trigger JavaScript functions on a webpage via a URL to that webpage), please let me know. It's important to note that there are 8 tags(elements) in total, and they all have to be triggered for the game/app to end, which requires it all to be done on the same page, preferably without refreshes(although I could probably rig something up using localstorage so it could be refreshed).
Thanks in advance, I'm just not sure how I would proceed here.
-Mitchyl
EDIT - I should mention that I already am using backbone.js for my routing needs. It's perfect for my situation at the moment,
What you need is a hash tag routing libary. http://projects.jga.me/routie/
This will run when your app page loads and read the hash, diverting the logic of your code to do something based on the hash tag, thus you make your items remove on the page in your code logic. No need for lots of pages.
But!
If the url launcher on the device launches new windows each time an item is detected, that is a problem since you can't close those windows, other than from the window itself.
Solution
The app has a main window for the game, each item is stored in local storage, You can use the local storage event system to detect if another page changes an item, and update the UI in real-time.
addEvent(window, 'storage', function (event) {
if (event.key == 'item1') {
item1.innerHTML = event.newValue;
}
});
When NFC launches a new window, display user feedback that states they have completed a task of the game then close it using a timeout.
Below that window will be the main page window with the update displayed.
Done properly it will work brilliantly. You can also add a nice x close button on the pop windows as tasks are completed.

How can I use Javascript to control other window from Firefox Scratchpad, even when it reloads?

I want to move my email from a somewhat unreliable provider (let's say X) to Gmail.
Unfortunately email provider doesn't allow folder export or direct IMAP link.
The only thing I can do is connect Gmail to X via POP3, so that anything in X's inbox gets copied to Gmail.
This I have set up, and it works, but of course POP3 only scans inbox.
I have thousands of emails in other folders than inbox, so I need to move them to inbox first. However, I can only move messages via X's web GUI, which only allows moving one page of messages per turn.
So I have to open Saved messages folder, click on "Select all", select "inbox" and click on "Move", then the page will reload and I need to do this again... hundreds of times.
I made a Javascript function (assume MoveToInbox()) which simulates these actions, and I opened page in Firefox and started Firefox Scratchpad. So, I can keep pressing Ctrl+R in Scratchpad, then wait for page reload, then press it again, which saves about 50% of time.
However, I am wondering, if I can somehow make Scratchpad work with that tab so that it waits for page reload, then executes script then waits again, eliminating all the manual repetitive tasks.
I thought I could somehow do it with window.addEventListener, but this object seems to get cleared on page reload, so is there something I could use instead?
My own quick answer is only by using a Firefox addon such as GreaseMonkey.
The solution will, of course, vary in different cases, but my own was this GreaseMonkey Javascript:
// the function to select all messages and programmatically click on
// move button:
function moveToInbox()
{
selectAllCheckbox=document.getElementById("messagesForm")[0];
mailboxSelector=document.getElementsByName('targetMailbox')[0];
selectAllCheckbox.click(); // click on "select all" checkbox
mailboxSelector.selectedIndex=1; //specify that we are moving to inbox
inx.mail.mailbox.mailboxTransfer(); // execute provider's function for moving mail.
}
// This gets executed on any page that matches URL specified in Greasemonkey script properties
// I have put this to execute, if the URL is for the folder I want to move messages from.
messageList=document.getElementById("messagesForm")[0];
// in my case, if there are no more messages to move, the form is not created at all, so
// I can check for its existance, to determine if I need to execute moving.
if (messageList == null)
{
return;
}
else
{
moveToInbox();
}
Using an iFrame
The first problem is that variables and functions get lost after reloading:
-Use an <iframe> with src = "X"
Now the Cross domain policy is causing troubles:
-Make the <iframe> on the same website as the src
Then, you can easily access and manipulate the website with iframeId.contentDocument
An example:
Navigate to google.com, use Inspect Element to add an iframe:
<iframe src="https://www.google.ae" id="someID"> </iframe>
Then, you can use JavaScript to do anything with the iframe:
someID.contentDocument.location.reload();
setTimeout('someID.contentDocument.getElementById('lst-ib').value="iframes rock"',1000); //You should use something better than setTimeout to wait for the website to load.

Automatically perform javascript function on pageload of external website

So I want to have a link to a site x (which I am not the developer of) that automatically performs some javascript function after it is clicked. EG.
javascript:window.location="http://www.google.com"; alert("Hello");
This performs the alert function before loading the page which is not desired.
Does anyone else know how this can be achieved?
Thanks.
If you load it in an iframe, I guess you could somehow wait for a certain element to be present and then execute your code.
You cannot do that.
Doing this, poses a security threat (XSS), and therefore disallowed by almost all the browsers!!
Worst scenarios to think of, if you had this control:
The Script to capture the username/pass of the user and mail it to you by further calling an Url.
Could play a role in unwarranted tracking/spamming.
EDIT:
This can be done only if user interaction in involved.
For eg:
You can ask user to drag a link to his bookmark toolbar, and the link should contain:
Test Click
And then to whatever page the user goes, whenever he clicks the bookmark button (link), an alert happens (or whatever script you may put.)
If the link is changing the "current" windows location, you cant execute your scripts after the external page has started loading.
You can't.
A walk around way is to put the site in to an iframe in your page. Then alert your message in its onload event. And of course your url on address bar will not change.

What to do when browser back button doesn't have the intended effect

I have a page where navigation is handled by hiding and showing preloaded divs when users click on links. But, the users think they've actually changed pages, so they click on their browser's "back" button trying to go back to the div that was previously hidden. But of course, they go back to the page from which they came.
What's the best way to handle this? 90% of the traffic is from a login page. Should I just sandwich a redirect page in between the two? How is this done? Can I just change the browser's back button behavior?
If you are already using jQuery, why not simply add a history manager like jq-bbq or the hashchange or history manager? (Or, if you want to really go all out, switch to a MVC JavaScript framework like Sammy.) That way, the back button will work as the user expects, rather than hacking around their expectations by blocking the back button or throwing in redirects. (Unless you have a good reason to, of course :-) )
If you use a browser history plugin like the jQuery UI one you end up changing the history so that the back button doesn't actually unload the page.
http://yoursite.com
-> User clicks something
-> new address bar reads http://yoursite.com/#/something
because of the hash mark when user goes back it goes back to http://yoursite.com which should inturn fire your show previous div function
read more about the available history manager plugins available for jQuery. There are quite a few. Most if not all provide available callback functions that you can specify.
On change of the state of your page, write a unique set of parameters to the hash of your URL. You can change this via JS without causing the page to reload.
Set a timer on the page that checks the current location hash repeatedly, and if it changes (i.e. the user presses the Back button) then update the state of your page to match the URL.
I have this scheme working to great effect in a local application.
The jQuery Address library is another great alternative.
http://www.asual.com/jquery/address/
You can set the URL for different application states, and get the URL 'parameters' when the page reloads.
Two ideas:
1) onbeforeunload. Ask the user if they want to really go back.
2) Sandwidch a redirect page. Login -> redirect -> your page. A single back click would take the user to your redirect page.
The second is kind of a pain in the neck for people who know what they're doing though. I think the Back button (and all standard navigational elements) should be messed with as little as possible.
I would go with onbeforeunload:
function sure()
{
event.returnValue = "sure?";
}
...
<BODY onbeforeunload="sure()">

Is it possible to add a browser code in javascript

I would like to create a webpage with browser specific in javascript.
For example:
can I use code like this in my coding part
chrome.tab.onRemoved.addListener() in my webpage.
If it is possible please suggest me.
What exactly are you tring to acheive?
If you want to know when the tab in which your webpage is loaded is closed, then window.onunload should help you.
If you want to know when another webpage is closed, you cannot do this.
UPDATE:
You said that you want to know when the user closes the browser or tab. This is not possible.
But for your purpose (getting feedback), I think all you need is to differentiate whether the user is navigating to a link in your page, or whether the user is typing another URL(or by clicking a favorite).
I think for your requirement, whether the user closes the browser, or whether he types another URL, is the same - the user is navigating away from your site, and at that time you say you want to collect feedback.
This can be done in javascript.
For all the clicks in your page that
might lead to a page refresh
(hyperlinks, buttons,...), set a flag.
In window.onunload, check whether
this flag is set.
- If it is set, then
the user has clicked a link in your
page, do nothing.
- If the flag is not
set then the user is navigating away,
time to collect feedback.
Let me know if this would work.
PS: Note that popups/any distractions during window.unload can be very annoying.
I understand that this probably is the requirements given to you. But if possible, try other mechanisms to collect (voluntary) feedback from the user.
No, you cannot access extension-specific APIs from webpages.
The Navigator object contains all information about the visitor's browser.
https://developer.mozilla.org/en-US/docs/Web/API/Window.navigator
I think this is pretty much the extent of what is possible in terms of interacting with the specific browser. You can't access other tabs (for security reasons) or tell when a tab is closed.
You can use use the onbeforeunload event:
<html>
<head>
<script>
var exit = 1;
function handleClose()
{
if (exit)
{
alert("Closing");
}
}
</script>
</head>
<body onbeforeunload="handleClose()">
Navigate to other page
</body>
</html>

Categories