views:

47

answers:

2

Hi! As I understand there is no way I can get dynamic server time in IE with settimeout() in script.. I found this example:

function  timeExam(){

    $.ajax({
    url : "inc/clock.php",
    success : function (data) {
    $("#clock_time").html(data);
    }
    });

           var func = function()
            {
                timeExam();
            }

            setTimeout(func, 1000);
    }


            <body onload="timeExam();">
                bla bla bla
            </body>

Maybe it is possible to make it work?

If not, could you please suggest me a dynamic clock with server time that works in all browsers?! I tried a clock with prototype.js but it conflicted with jquery UI in IE8(showed selectmenu incorrectly). I added that no conflict code to script but it was useless.. had to remove prototype.js

A: 

Since you're using jQuery:

$(function() {
  var updateSeconds = 60;
  function updateClock() {
    $.ajax({
      url : "inc/clock.php",
      success : function (data) {
        $("#clock_time").html(data);
        setTimeout(updateClock, updateSeconds * 1000);
      }
    });
  }
  setTimeout(updateClock, updateSeconds * 1000);
});

Change "updateSeconds" however you want.

I did this with setTimeout instead of setInterval because it's a little safer. If there's a server problem, this one won't pile up doomed HTTP requests over and over again, because it doesn't set up a new update until the current one succeeds.

Pointy
missing few bracket... but smth doesn't work.. not showing time at all.
arturs
Well do you know what your server is actually returning? You can use Firebug (Firefox) or the IE8 debugger to check the response from the XHR.
Pointy
no activity.......
arturs
You're the only person who can directly diagnose the issue, @arturs. Put "alert()" calls in the timeout function to make sure it's being called. Check the browser "Developer tools" and your server logs to see whether the ajax request is failing to do some error.
Pointy
@arturs do you have the clock.php serverside script setup correctly?
Daniel Baulig
@Pointy but setTimeout will also kill the clock if there was a single failed XHR, eg due to high server load, or a bittorrent cluttered client connection or whatever other valid reason you can think of (loosing UMTS network in a train, server down/restarting for maintainance, you name it). Depending on the type of application this might not be desireable behaviour.
Daniel Baulig
@Daniel yes that's a very good point - it might be good to have an error handler for the $.ajax to make some decision, or possibly an interval "watchdog" to do the same thing (at a relatively long interval).
Pointy
Ok, It works in firefox and partly in IE. I set updateSeconds = 60 to 1 so it updates every second..(bad thing is that when I open the page, colck doesn't show up for 1 second). It just didn't show up first 60 sec.. alert() works too in both. But in IE clock is not updating.. it shows the time when the page was opened. only closing a browser and opening it again updates the clock...
arturs
I forgot to say that IE gives error "Object doesn't support this property or method." Code 0 Char 7. It might be smth with GET.. I had script where I changed it to POST and it worked.
arturs
As @Daniel says, doing a clock update via HTTP request once per second might get a little annoying to your users. That's why I set my example up as something that'd run once a minute. You could do as @Daniel suggests and run a client clock update once per second, and then grab the server time once a minute.
Pointy
+1  A: 

What your script does is poll a script on your server at inc/clock.php and replace your #clock_time element's contents with the output from the script (roughly) every second. This should work, provided you have a element with id clock_element and a script at yoursite.tld/inc/clock.php

However, I disagree to constantly poll the server for it's current time. It should suffice to sync time only once to your webserver. Beside some minor differences this should keep your clocks synced well enough for a good while. If your webapp will run more than a couple of hours or days you should periodicly resync your clock (once a day or a week should do).

Use a Date object to keep track of the servertime on your client. Simply create a Date object from the output of clock.php (a valid date output as prerequisite) and update your clock_element periodicly (like every second) according to the time delta from when you synced your clock with the remote server.

Here some rough code, not tested, propably some syntax errors, but briefly shows what you should do:

function setupServerClock( clock_element, remote_time_url, remote_update_interval, local_update_interval ) {
    var w = window;
    // client time on resync
    var ct = new Date();
    // server time on resync
    var st = new Date();
    // setup resync
    w.setInterval( function() {
        jQuery.ajax( {
            url: remote_time_url,
            success: function (data) {
                ct = new Date();
                st = new Date(data);
            }
        });
    }, remote_update_interval);
    // setup local clock display
    w.setInterval( function() {
        // the time passed on our local machine since the last resync
        var delta = new Date() - ct;
        // we assume the same time passed at the server
        // (yeah, I know, spacetime might not be the same at the servers 
        // place and off the shelve clocks are pretty inaccurate)
        var clock = st - 0 + delta; // - 0 to convert to microsecond timestamp
        jQuery(clock_element).html(new Date(clock));
    }, local_update_interval);
}

Call it with something like:

setupServerClock( jQuery('#clock_element'), 'inc/clock.php', 1000 * 60 * 60, 1000 );

This will setup the clock to be written to #clock_element, using the value returned from yourdomain.tld/inc/clock.php, resync the clock every hour and update the local representation of the clock every second.

Oh and if that periodical resync indeed brings up "jumps" in the clock you could think about simply giving the user feedback, that his clock was updated, eg like this

    w.setInterval( function() {
        jQuery(clock_element).html('resyncing clock...');
        jQuery.ajax( {
            url: remote_time_url,
            success: function (data) {
                ct = new Date();
                st = new Date(data);
            }
        });
    }, remote_update_interval);
Daniel Baulig
Well there's not really any way to "synchronize" the client clock with the server; you just don't have that ability from Javascript code in a browser. If the client clock is drifting, then the client code would have to do some sort of adaptive adjustment, which would be pretty complicated.
Pointy
Of course I am talking of his #clock_element as "client clock"
Daniel Baulig
Yes I understand that. What I mean is that if he *really* wants an accurate display of actual time at the server, the simplest way to do it is pretty much what he's got set up. An HTTP request once a minute or so isn't really that bad. Now, if it's desired that the clock tick off seconds, well, I guess I'd do that at the client, but the inevitable "jumps" when the actual server time differs by a second or two might be distracting. Depends on the application I guess.
Pointy
Due to network lag, the way javascript asynchronous functions (including $.ajax and setTimout) work and finally the inaccurate system clocks you can neer rule out that one or two distracting seconds. Besides he did not query the server "once a minute or so" but actually on every single clock update, which occured roughly every second.
Daniel Baulig
@Daniel yes that's true - and I certainly wouldn't do it once per second.
Pointy