Kode Charlie
Kode Charlie

Reputation: 1499

In PhantomJS, why does jQuery call cause script to hang?

I'm using PhantomJS 2.0.0, on a Mac OS X Yosemite:

$ phantomjs --version
2.0.0

My script, shown below, appears to hang at the line where $('h1').size() is called:

system = require('system');

function usage() {
  console.log("usage: phantomjs " + system.args[0] + " <url>");
  phantom.exit(1);
}

console.log("system.args.length=" + system.args.length);
if (system.args.length != 2) {
  console.log("usage bad....");
  usage();
} else {
  var url = system.args[1];
  var page = require('webpage').create();

  console.log("Opening page: " + url);
  page.open(url, function (status) {
      if (status !== "success") {
        console.log("Unable to access network");
      } else {
        console.log("Setting timeout...");
        window.setTimeout(function() {
          page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js", function() {
            console.log("Searching for Seawolf Calendar...");
            console.log("h1.size=" + $('h1').size());

            console.log("Exiting with status 0...");
            phantom.exit(0);
          });
        }, 5000);
      }
  });
}

The script is invoked from the command-line like this, for example:

phantomjs download-framed-content.js "http://www.sonoma.edu/calendar/groups/clubs.html"

with output like this:

system.args.length=2
Opening page: http://www.sonoma.edu/calendar/groups/clubs.html
Setting timeout...
Searching for Seawolf Calendar...

[Hung ...]

Why is the jQuery call hanging the script?

Upvotes: 2

Views: 225

Answers (1)

Artjom B.
Artjom B.

Reputation: 61962

PhantomJS 2.0.0 doesn't show any errors for some reason (this is a known bug).

The error would be that $ is not a function. If jQuery is present in the page, then you can use it in the page, but it won't work outside of the page context (inside page.evaluate()).

You can only access the DOM/page context through page.evaluate():

console.log("h1.size=" + page.evaluate(function(){
    return $('h1').size();
}));

Note that you cannot use any outside variables inside of the page.evaluate(), because it is sandboxed. The documentation says:

Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.

Closures, functions, DOM nodes, etc. will not work!

Upvotes: 1

Related Questions