1

Here is some code for my problem:

var jsdom = require('jsdom');

var content = '\
    <p>\
        <img src="assets/logo">\
        <img src="assets/background">\
    </p>\
';

jsdom.env(content, function (error, window) {
    var $ = require('jquery')(window)
    var elements = $.find('img');

    elements.forEach(function(imageElement) {
        var src = $(imageElement).attr('src') + '.jpg';

        $(imageElement).attr('src', src);

        // print "assets/logo.jpg" and "assets/background.jpg"
        console.log($(imageElement).attr('src'));
    });

    console.log(content);
});

What I'm trying to do is, changes the content of src on every img elements to assets/logo.jpg and assets/background.jpg.

Can anyone suggest me, what must I do so that the content will be change to: <p><img src="assets/logo.jpg"><img src="assets/background.jpg"></p>?

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
Crazenezz
  • 3,416
  • 6
  • 31
  • 59
  • 2
    Assign the new `innerHTML` to `content`? Check the jsdom docs for how to serialize a DOM back to html. – Bergi Dec 02 '14 at 12:44
  • @Bergi: What I mean is, I want to change the `content` from this line of code `$(imageElement).attr('src', src);` but unfortunately it cannot change the `content` value directly. – Crazenezz Dec 02 '14 at 12:50
  • Of course you don't. `content` is a string. The DOM is not stored in a string, what you are manipulating is a tree of nodes. The string from which you created the DOM will stay unaffected. You need to serialize it back into a new string. – Bergi Dec 02 '14 at 13:07
  • @Crazenezz I've rolled back your edit. Please don't add a new question to your question. Otherwise, what you are creating is a ["chameleon question"](http://meta.stackexchange.com/questions/43478/exit-strategies-for-chameleon-questions) If you have a new issue, then post a new question. Make sure you read the other SO questions that pertain to your problem though. Thank you. (It may look like the same problem to you but what you added is really a *different* problem.) – Louis Dec 02 '14 at 13:27
  • @Louis: Not new question, just want to show you what I do with my code, and I think this question is related to http://stackoverflow.com/questions/9419242/how-do-i-return-a-value-from-a-simple-jsdom-function – Crazenezz Dec 02 '14 at 13:29
  • @Crazenezz It *is* in fact a new question. What you asked here was about how to get your `console.log` to print the modifications you made to your DOM tree. **This question was answered.** Now you are asking a *different* question which is "how can I get the result of an asynchronous operation." – Louis Dec 02 '14 at 13:32
  • It's difficult to tell what your edit was meant for, Crazenezz, but it definitely wasn't in line with just adding details for this specific problem, as @Louis notes. – Andrew Barber Dec 02 '14 at 21:56

1 Answers1

1

You should use something like this to serialize the DOM:

console.log(window.document.body.firstChild.outerHTML);

As Bergi pointed out in the comments what jsdom manipulates is a DOM tree, jsdom won't go back to the source HTML and change that. What you have to do is serialize the DOM tree and you do this using the usual DOM methods. The window.document.body.firstChild bit gets you your paragraph. The .outerHTML bit is how you get the serialization of your paragraph.

Another way is to do:

console.log(window.document.body.innerHTML);

In your case, it does the same thing as the first method. Instead of asking for the serialization of the paragraph, this is asking for the serialization of the contents of the body element (which happens to be the paragraph's parent).

If you wonder why we have to fuss about body, this is because jsdom acts as a browser: it takes what you give it and cleans it up so that it looks like proper HTML. Once jsdom has parsed your source but before you modify it, this is what it looks like, structurally:

<html>
  <head></head>
  <body>
    <p>        
      <img src="assets/logo">
      <img src="assets/background">
    </p>
  </body>
</html>

(The above is pretty-printed to highlight the structure. The whitespace between elements is certainly off.)

Louis
  • 146,715
  • 28
  • 274
  • 320