2

I have an HTML document that I receive from the server via an Ajax call and I obviously receive that HTML document as a string :

var serverResponse = "<html><head>.......";

I now want to alter parts of this HTML document and then send it back to the server as an HTML string.

Changes include adding/editing attributes and their values (e.g. style="", src="", href="") as well as changing some innerHTML etc..

There are two ways of achieving this :

No.1 : I can either loop through the whole string and apply some elaborate regex every time in order to find the value I want and change it or add new values etc..

No.2 : I can go for the easiest solution which is converting that string into a jQuery object and then easily traverse that and change it.

I believe the 2nd option has the undesired side effect of actually loading files (like images or evens scripts), at least on some browsers (like IE ?). Please correct me if I'm wrong and if there's nothing to worry about then I'll just go for the 2nd option.

example :

I know I can do the following :

var $html = $(serverResponse);

(I know jQuery.parseHTML() does the same as the above..)

And then perform my changes by doing stuff like :

$html.find('.some-div').eq(2).css('background', 'url(http://some-new/img.jpg)');

Once I'm done with the changes I then need to convert the updated HTML back into a string and post it back to the server.

Do you have any suggestions ?

4
  • AFAIK I don't think you can prevent it, but maybe run a regexp that change the src= to data-src= or something. then when you're ready to load them, do the inverted operation. Commented Mar 13, 2015 at 18:30
  • 1
    If you specify your broader goal, it might be possible to provide an alternative solution that would be easier than trying to escape the html string. For example, are you trying to template? Webscrape? Something else? Commented Mar 13, 2015 at 18:32
  • I don't think scripts in detached dom nodes are excuted, as far as I can tell the standard specifies that they should be executed on insertion Commented Mar 13, 2015 at 19:43
  • You are right maybe it's worth stating more clearly what I'm trying to achieve. Please see my updated OP. Commented Mar 13, 2015 at 21:07

3 Answers 3

2

By default jQuery will work on the document object, it will parse the HTML and attach the nodes to the document. Create a separate DOM Document for your HTML.

var context = (new DOMParser()).parseFromString(serverResponse , 'text/html');
jQuery('.some-div', context)
  .eq(2)
  .css('background', 'url(http://some-new/img.jpg)');
Sign up to request clarification or add additional context in comments.

3 Comments

Does that mean that this way the scripts will not be executed and files will not be loaded ?
No the browser renders the document object, so it fetches the resources for it. A separate DOM Document instance is not rendered by the browser (it is just another variable).
What is the Browser Support on this ? I couldn't find any information online I'm afraid..
1

As Dan Field said, It's better to say your final goal. Probably someone know better solution for your goal. However, I think you want to remove images after creating DOM object. For this purpose, you can do this:

var $html = $(htmlAsString);
$html.find("img").removeAttr("src");

Or, if you don't want to lose image src, you can do this:

    $html.find("img").each(function(){
        var src = $(this).attr("src");
        $(this).removeAttr("src");
        $(this).attr("data-src", src);
    });

1 Comment

You are right maybe it's worth stating more clearly what I'm trying to achieve. Please see my updated OP.
0

For browsers support <template>, you may use it to archive this easily:

var template = document.createElement('template');
template.innerHTML = '<img src="1.jpg" /><script>alert(42)<\/script>';
console.log([...template.content.children].map(i => i.outerHTML));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.