Refresh one section

I use the following function to load content in a div and to refresh the loaded content every 2 seconds to see if anything has changed:


$(function () {
    var timer,
        updateContent;
    function resetTimer() {
        if (timer) {
            window.clearTimeout(timer);
        }
        timer = window.setTimeout(updateContent, 2000);
    }
    updateContent = function () {
        resetTimer();
        $.get('modules/berichten.php', function (data) {
            $('#main').html(data);
        });
    };
    updateContent();
    $(document.body).on('mousemove keydown', resetTimer);
});

But actualy would like to exclude certain elements (textarea and h1 tag) from beeing refreshed. Is this possible?

Thank you in advance!

You can. Are you sure you have to? If the text is still the same, I think I would just replace all of it and be done with it.

Otherwise you can read a part of the result, and use that. Something like


updateContent = function () {
    resetTimer();
    $.get('modules/berichten.php', function (data) {
        var resultDom = $(data);
        $('#main some-element').html($('#main some-element', resultDom));
    });
};

(not tested, but should work)

I have to say that every 2 seconds is quite a lot, I would seriously consider to that every 10 seconds, or use longpolling or websockets instead.

I would also move the setTimeout function to the callback of your $.get function, so you can be sure that the next one will fire once the previous one is done. Otherwise you might end up with a whole queue of AJAX requests that haven’t fired yet. Like so:


$(function () {
    var timer,
        updateContent;
    function resetTimer() {
        if (timer) {
            window.clearTimeout(timer);
        }
    }
    updateContent = function () {
        resetTimer();
        $.get('modules/berichten.php', function (data) {
            $('#main').html(data);
            [COLOR="#FF0000"]timer = window.setTimeout(updateContent, 2000);[/COLOR]
        });
    };
    updateContent();
    $(document.body).on('mousemove keydown', resetTimer);
});

Oops this is a lot of info :slight_smile:

I am not sure what you mean with this. The main thing I would like to exclude from the refresh is a form. No mather how many seconds I use for the timer, the info added to the textarea in that form should remain when the page is refreshed!

Is the (some-element) in this


        var resultDom = $(data);
        $('#main some-element').html($('#main some-element', resultDom));

the part that will be excluded? Or is that the section that will be refreshed.

I am still try to figure what would be the best for my needs. I got some suggestions about longpolling before but couldn’t figure how that is working as yet. I will follow your advice to extend the refresh to 10 seconds.

Thank you very much for this tip, already implemented.

Wouldn’t it be easier if the php script would just return the part(s) that needs refreshing?
If you’re using the same PHP script you can differentiate between normal requests and AJAX requests via $_SERVER[‘X_REQUESTED_WITH’], which will be empty for normal requests, and ‘XMLHttpRequest’ for AJAX requests.

That is the section that will be refreshed. The code basically says to replace that element in the current DOM with that same element from the AJAX result.

Longpolling is basically that you send an AJAX request but the PHP only responds once it has something new to tell. So the AJAX request would send the newest ID of a message it knows, and then PHP will query the database every second or so, and when there is will respond with that messsage.
The theory behind it is pretty nice and straigtforward, but it does use resources for nothing, and you have to make sure the connection stays open, i.e., that PHP doesn’t time out, your webserver doesn’t time out, etc.

Out of curiosity, how many messages do you expect to be processing on average?

Hi ScallioXTX thanks again for the reply :slight_smile:

I wish I could. The part that I don’t want to be refreshed is to much integrated in the design. I have been thinking the entire evening If I could do it differently, but without result sofar. I am not sure what you mean with:

normal requests and AJAX requests via $_SERVER[‘X_REQUESTED_WITH’],

So you can only include elements and not exclude elements. Is it also possible to include multiple elements or ist that overdone?

Like I said someone already suggested Longpolling and the last hour or so I have been looking into html5 websockets. It seems very interessting and I will for sure do some more research into that!

I mean you can use the same PHP for both regular requests as well as AJAX requests, if you wanted to.
My idea was that you are using the same URL to load the page as you are for loading the AJAX request, right? If so, you could return only the relevant parts in the AJAX request in a JSON array or something, and pick them out and replace them on the website.

Yes you can include multiple elements by repeating that line several times with different elements. If you include anything you want you’ve effectively excluded everything you don’t want :wink:

When you do I would suggest you don’t write the client in PHP, but another language that has threading, like Google Go.

Hi ScallioXTX

I have followed your instructions. For the moment I upgraded the refresh time to 10 seconds and have changed the update content function the following way:


    updateContent = function () {
		resetTimer();
		$.get('modules/berichten.php', function (data) {
			var resultDom = $(data);
			$('#main .berichten').html($('#main .berichten', resultDom));
		});
	};

where .berichten is an unsorted list of messages. If I understood you well this would be the section that should be refreshed, right? However, for some odd reason the entire content disappears.

I do not know enough Javascript (dom) to know how I should adjust this :frowning:

Hi donboe,

I checked it locally, and it should be


updateContent = function () {
    resetTimer();
    $.get('modules/berichten.php', function (data) {
        var resultDom = $(data);
        $('#main .berichten').html($('#main .berichten', resultDom).html());
    });
};

I tested (a variant of) this locally and it works just fine.

I still would load only the stuff you need instead of loading everything and picking out pieces, but maybe that’s just me :slight_smile:

Hi ScallioXTX. Thanx for the reply.

I keep getting a blank screen even if I just use:

$('#main').html($('#main', resultDom).html());

I indeed, probably, should approach this differently?

I certainly would. This way is way too fragile and might fall over in new browsers that dont understand what’s going on.
Do you need to replace one element or several?

Hi ScallioXTX, again thanx for the reply. It is just one div holding a form What I try now is to have a parent div holding the form and the main div where the content is loaded in. I keep you informed how it will go.

Hi ScallioXTX. I followed your advice to take the form out from the content that is loading and refreshing (every 10 seconds) and place it in the main berichten page by positioning it absolute within the parent div. Everything is working fine. Thank you for all your input and help. It is very much appriciated :tup: