Question

I am trying to trigger a scroll event or a keypress event on a window that I have loaded under jsdom. I have loaded the window using jsdom.jsdom() function, and it has the external resources loaded (i.e.. the scripts on the page itself). Basically I am trying to trigger these events so that the javascript on the page can listen to those events and loads the next page of data, as the page has the autoload feature when the scrolled to bottom. But I am having trouble with just triggering the scroll event, let alone triggering scroll to the bottom of the page. It is just getting stuck, nothing is happening.

I also tried to trigger keypress event with the key of end but for that I am not even able to set a handler for keypress. again getting stuck.

I am using jsdom.jqueryify() on the window to embed jquery code in it. I thought with that I could use jquery function like .scroll() to set a test handler, but again it is getting stuck, without giving any error messages. Here is the code:

var document = jsdom.jsdom(str, null, {});
var window = document.parentWindow;

jsdom.jQueryify(window, "jquery.js", function () {
    $(window).scroll(function(){
        console.log("Scroll Happened.");
    });
    console.log("Triggering Scroll event...");  // 1
    $(window).trigger('scroll');
    console.log("Scroll event triggered.");     // 2
}

This code does not even reach 1st position, however if I change $(window) to window it crosses 1st position but still doesn't reach 2nd position.

I also tried:

window.dispatchEvent('scroll');
window.scrollByLines(1);

instead of:

window.trigger('scroll');

but no change. Any help will be appreciated. Thanks

Was it helpful?

Solution

The issue is pretty simple: $ is not defined in the context in which your code executes. The fix is to add to your callback the parameters window and $. They are initialized by jQueryify as you'd expect. The following outputs to the console everything you wanted:

var jsdom = require("jsdom");

var document = jsdom.jsdom();
var window = document.parentWindow;

jsdom.jQueryify(window, "jquery-1.10.2.js", function (window, $) {
    try {
        $(window).scroll(function(){
            console.log("Scroll Happened.");
        });
        console.log("Triggering Scroll event...");  // 1
        $(window).trigger('scroll');
        console.log("Scroll event triggered.");     // 2
    }
    catch (ex) {
        console.log(ex);
    }
});

I've added the try ... catch for illustration purposes. If you remove window, $ from the parameters, you can see that the try ... catch catches a ReferenceError because $ is not defined.

The lesson here is that jsdom effectively creates a new JavaScript virtual machine in which it executes the scripts loaded by the window. So symbols that are defined in this virtual machine are not necessarily defined outside of it. And symbols of the same name that are defined inside the jsdom virtual machine and outside of it do not generally point to the same object. (For instance, console outside the virtual machine created by jsdom and console inside of it are not the same object.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top