简体   繁体   中英

How can I clone a window server-side using jQuery?

I am currently running AngularJS server-side using Node.js and jsdom . It's working great, but I'm trying to optimize performance by caching the DOM generated by jsdom before the AngularJS scope is applied to the page. Trouble comes when I try to clone my cached DOM before applying the AngularJS scope for a given request. Currently, I'm cloning the cached DOM by using jQuery (server-side):

var clone = cachedWindow.$("html").clone(); // This part works fine

Then, I create a new window using jsdom with no content inside the html tag (fast):

jsdom.env(
  '<!doctype html><html></html>',
  injectedScripts, // This is where I inject AngularJS, which works fine
  function(errors, newWindow) {
    newWindow.angular.bootstrap(newWindow.document, ['ngView']);
    newWindow.$("html").replaceWith(clone); // This part does not work
  }
);

The problem comes from newWindow.$("html").replaceWith(clone); which generates this error:

{ code: 4, message: 'Wrong document' }

I understand the issue to be related to the fact that I'm trying to replace a DOM element within one document ( newWindow ) with a DOM element coming from another document ( cachedWindow ), but I can't think of any way around that. This is important, because cloning the html element is about ten times faster (literally) than rebuilding the DOM from scratch with jsdom...

Any suggestions?

Notes:

  • On one hand, the solution I'm looking for needs to work with jsdom.
  • On the other hand, I'm not married to jQuery. Any alternative would work just fine.
  • Window cloning is required to prevent issues with concurrent requests and to support sessions.
  • For more background, please check CircularJS on Sutoiku

Solution:

Offered by Jason Livesay , using document.importNode

var original = cachedWindow.document.getElementById("app");
...
var clone = newWindow.document.importNode(original, true);
newWindow.document.getElementById("app").appendChild(clone);

When I google that "Wrong Document" thing I see a bunch of PHP XML stuff that mentions importNode. So maybe you can use that in JavaScript too: https://developer.mozilla.org/en-US/docs/Web/API/document.importNode

Or maybe something like this: http://jsdom.wordpress.com/2011/03/14/appendchild-problem-in-google-chrome-and-safari/

Also if you are looking to optimize that part, just to double check, you are saving the final HTML to disk right? I mean you're not rendering the static page on every single request are you?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM