Alex
Alex

Reputation: 68416

Replace content of a web page with stuff from AJAX response

The idea is to replace the contents of a web page with the same page requested through an ajax call, but only the HTML elements that are different.

Current I have this in my $.ajax success callback:

var replace = function(first, second){

  $(first.html() !== second.html())
      first.replaceWith(second);

};

replace($('#container'), response.find('#container'));

Which works, but because the content gets always replaced I get to see a "clipping" effect. The ajax request runs multiple times, almost every second, until a certain class is added to the container tag from the ajax response, so the clipping is very annoying.

Basically I want to only replace the elements that have different html, but somehow start from the last level, to prevent replacing of elements that have the same html code.

I made a fiddle example here: http://jsfiddle.net/2u4eB/

So in that markup only the contents of the <b> tag should be replaced, and not the entire div like it is now, because only <b> is different.

Does anyone have any pointers on how could I achieve this?

Upvotes: 2

Views: 939

Answers (2)

JR Kincaid
JR Kincaid

Reputation: 823

I highly recommend using a framework that supports client side binding. (Examples include but are not limited to Knockout, Handlebars, Angular, Underscore) This will give you better results faster than writing low level DOM Manipulation.

Knockout.js and Underscore.js are my favorites, but there are many great options.

Upvotes: 1

Ryan Wheale
Ryan Wheale

Reputation: 28390

If you can make some assumptions, then it's not so hard:

  • Assumption 1: The markup is exactly the same every time
  • Assumption 2: The only thing which changes is the TEXT inside of certain html tags

You must then know the HTML tags. If you are a consistent person, all of your dynamic data should be wrapped in a similar tag - in your question you mentioned a <b> tag, so lets make a third assumption:

  • Assumption 3: All dynamic data is wrapped with a <b> tag

Then all you have to do is this:

var replace = function(first, second) {
    var oldValues = first.find('b'),
        newValues = second.find('b');

    oldValues.each(function(i) {
        if(oldValues[i].textContent != newValues[i].textContent) {
            oldValues[i].textContent = newValues[i].textContent;
        }
    });
};

replace($('#container'), response.find('#container'));

NOTE: this works because jQuery's find() returns a list of nodes in document order - so Assumption #1 is very important.

Upvotes: 1

Related Questions