npm install jsdomjsdom is very easy to use:
var htmlSource = fs.readFileSync("dummy.html", "utf8"); call_jsdom(htmlSource, function (window) { var $ = window.$; var title = $("title").text(); $("h1").text(title); console.log(documentToSource(window.document)); });Above, we first read html source from disk into a string, then we invoke jsdom with that source. It calls us back when everything is finished, with a window object. To make things easier to understand, we have used the custom function call_jsdom() that hides a few unnecessary details and loads jQuery “into” the window. Hence, we only need to access window.$ and can work with jQuery as we would in a browser: The document does not yet have a heading, so we read the title and put it into the empty h1 tag. Finally, we log the transformed HTML to the console. To try it out, you can download the complete project jsdom_demo; run transform.js on the shell, either directly or via Node.js. The input is:
<!doctype html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>My document</title> </head> <body> <h1></h1> </body> </html>The output is:
<!doctype html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>My document</title> </head> <body> <h1>My document</h1> </body> <script src="jquery-1.7.1.min.js"></script></html>
var fragment = $("<ul><li>item</li></ul>");Seeing thrown exceptions. jsdom catches all exceptions. Unfortunately that catching extends to its callbacks. For example, the following is a function that we have called previously.
function call_jsdom(source, callback) { jsdom.env( source, [ 'jquery-1.7.1.min.js' ], // (*) function(errors, window) { // (**) process.nextTick( function () { if (errors) { throw new Error("There were errors: "+errors); } callback(window); } ); } ); }jsdom swallows all exceptions thrown inside the callback at (**), including in any functions that it calls. To escape that effect, you can use process.nextTick() to add a function to the event loop queue. It will be executed after the current code is finished.
Loading jQuery from a file. The examples in the jsdom readme load jQuery from a URL, causing internet traffic each time the code is run. A solution is to put a copy of jQuery next to the script and specify a file path instead of a URL, as seen above at (*).
Using jQuery multiple times. Do you have to invoke call_jsdom (or jsdom.env) every time you want to use jQuery? No, you can store window somewhere and use it again later. The initial startup is only callback-based to accommodate asynchronous script loading.