1

I want to understand how navigator.onLine works. For that purpose, I typed up a small snippet, which is supposed to check every 3 seconds if the browser is online, and if it is, pop up an alert:

function check_connection() {
var online = navigator.onLine;
return online;
}

function timed_alert() {

var perfectTiming = setInterval(check_connection,3000);

if (online) {
alert("ONLINE!");
clearInterval(perfectTiming);
}

timed_alert();

This thing doesn't work, for some reason. What have I done incorrectly? What should I change in the snippet to make it work?

KeithRules
  • 207
  • 1
  • 4
  • 14

4 Answers4

3

your alert and check need to be in the same function, along with the timer id (perfectTiming) being global.

var perfectTiming = null;
function check_connection() {
     var online = navigator.onLine;
     if (online) {
          alert("ONLINE!");
          clearInterval(perfectTiming);
     }
}

function timed_alert() {
    perfectTiming = setInterval(check_connection,3000);
}

timed_alert();

if you are trying to test to see if the user has an active internet connection that is harder as there is no real way for the browser to check this. You could however test several different ip/urls to see if they are reachable

var testUrlIndex = 0;
var testurls = [
    "http://www.google.com",
    "http://www.cnn.com"
];
function testURL(url)
{
    var xmlhttp;
    if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else
    {// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==0)
        {
                testUrlIndex++;
            if( testUrlIndex<testurls.length ) {
                testUrl(testurls[testUrlIndex]);
            } else {
                weAppearToBeOffline();
            }
        }
    }
    xmlhttp.open("GET",url,true);
    xmlhttp.send();
}

function weAppearToBeOffline() {
     //DO whatever you need to do if we are offline.
}
testUrl(testurls[0]); //start the check

This code will check 2 urls (just add more urls to testurls if u want to check more), if it goes though all of them and cant reach them it will call the weAppearToBeOffline function

Now this is only faulty in a couple ways, one mainly being that there is a situation where maybe the user is online but cant reach any of those urls but can reach others .

Patrick Evans
  • 41,991
  • 6
  • 74
  • 87
  • Thank you very much, @Patrick – but why does it output the alert even when the browser is online? – KeithRules Jun 27 '13 at 13:30
  • because that is what it is checking, to see if its online, if u want ot check if its offline, use `if (!online) {` `!` means not, so if online "not true" – Patrick Evans Jun 27 '13 at 13:32
  • I mistyped, sorry, @Patrick. It outputs the alert even when I unplug the Internet cable (and there's no wireless). – KeithRules Jun 27 '13 at 13:36
  • Edited my answer to include checking of urls to see if the user is offline. but it is potentially able to give a false positive. – Patrick Evans Jun 27 '13 at 13:49
2

make following changes:

var perfectTiming = setInterval(check_connection,3000);

function check_connection() {    
  if(navigator.onLine){
      alert("ONLINE!");
      clearInterval(perfectTiming);
  }
}
Zaheer Ahmed
  • 28,160
  • 11
  • 74
  • 110
2

You need to call timed_alert with a setTimeout and not check_connection.

function check_connection() {
    var online = navigator.onLine;
    return online;
}

function timed_alert() {
    var online  =check_connection();


    if (online) {
       alert("ONLINE!");

    }
    else{

       setTimeout(timed_alert,3000);
    }
}
timed_alert();
Gregoire
  • 24,219
  • 6
  • 46
  • 73
  • Why setTimeout, and not setInterval, @Gregoire? – KeithRules Jun 27 '13 at 13:21
  • @KeithRules because it is called in the function that is called by the trigger. If I had used setInterval I would have had a new interval set for each timed_alert function call – Gregoire Jun 27 '13 at 13:39
2

Your checking for the connection every 3 seconds, but your not doing anything with it. Call the timed_alert every 3 seconds instead and use check_connection within that function:

var perfectTiming = setInterval(timed_alert,3000);

function check_connection() {
    var online = navigator.onLine;
    return online;
}

function timed_alert() {
    if (check_connection()) {
        alert("ONLINE!");
        clearInterval(perfectTiming);
    }
}

This is the route to take if you plan to check_connection elsewhere in your script.

George
  • 36,413
  • 9
  • 66
  • 103
  • Solved? Glad to have helped. – George Jun 27 '13 at 13:23
  • Almost works... except it outputs the alert even if there's no Internet connection. Am I missing something, @F4r-20? – KeithRules Jun 27 '13 at 13:28
  • @KeithRules Please see [this question](http://stackoverflow.com/questions/2779367/navigator-online-still-true-when-turning-off-wifi-false-when-set-work-offline) (: – George Jun 27 '13 at 13:31
  • So, am I understanding correctly that I have to set Work Offline variable to true when check_connection returns false? Or am I misinterpreting the answer from that question, @F4r-20? – KeithRules Jun 27 '13 at 13:34
  • The navigator.onLine does not use the network connectivity of the machine itself, it uses the 'Work Offline' option in most browsers. Even if the computer has no connectivity, the 'Work Offline' option can still equal false. – George Jun 27 '13 at 13:36
  • Damn, this is getting confusing. Sorry, @F4r-20, I'm a JavaScript novice. What should I modify in the script to make the browser send alert when there's no connection? – KeithRules Jun 27 '13 at 13:37
  • You can't, not with `navigator.onLine` anyway. You'd have to make an AJAX request to an online server and check for a response every, 3 seconds, for example. – George Jun 27 '13 at 13:39
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/32497/discussion-between-f4r-20-and-keithrules) – George Jun 27 '13 at 13:40