开发者

How can I set JS to run in the background while remaining unobtrusive?

I have a small chat implementation, which uses a Message model underneath. In the index action, I am showing all the messages in a "chat-area" form. The thing is, I would like to start a background task which will poll the server for new messages every X seconds. How can I do that and have my JS unobtrusive? I wouldn't like to 开发者_StackOverflowhave inline JS in my index.html.erb, and I wouldn't like to have the polling code getting evaluated on every page I am on.


This would be easiest using a library like mootools or jquery. On domready/document.ready, you should check for a given class, like "chat-area-container". If it is found, you can build a new <script> tag and inject it into DOM in order to include the javascript specific for the chat area. That way, it isn't loaded on every page. The "chat-area-container" can be structured so that it is hidden or shows a loading message, which the script can remove once it is initialized.

On the dynamically created <script> tag, you add an onLoad event. When the script is finished loading, you can call any initialization functions from within the onLoad event.

Using this method, you can progressively enhance your page - users without javascript will either see a non-functioning chat area with a loading message (since it won't work without js anyway), or if you hide it initially, they'll be none-the-wiser that there is a chat area at all. Also, by using a dynamic script tag, the onLoad event "pseudo-threads" the initialization off the main javascript procedural stack.


To set up a poll on a fixed interval use setInterval or setTimeout. Here is an example, using jQuery and making some guesses about what your server's ajax interface might look like:

$(function() {
    // Look for the chat area by its element id.
    var chat = $('#chat-area');
    var lastPoll = 0;

    function poll() {
        $.getJSON('/messages', { since: lastPoll }, function(data) {
            // Imagining that data is a list of message objects...
            $.each(data, function(i, message) {
                // Create a paragraph element to display each message.
                var m = $('<p/>', {
                    'class': 'chat-message',
                    text: message.author +': '+ message.text;
                });

                chat.append(m);
            });                    
        });

        // Schedules the function to run again in 1000 milliseconds.
        setTimeout(poll, 1000);

        lastPoll = (new Date()).getTime();
    }

    // Starts the polling process if the chat area exists.
    if (chat.length > 0) {
        poll();
    }
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜