Search code examples
javascriptscrolluserscripts

Userscript working in Chrome but not in Firefox


This script searches for and grabs the closest element in a collection and scrolls to it depending on what key you press. It is set to scroll to the next and previous post_block elements on IP.Board forums. It also jumps through page with other keys.

It works exactly as expected in Chrome, but the scrolling doesn't work in Firefox. The page jumping does. It does not throw any errors, it just doesn't work.

Relevant code:

// Questionable functions
function getPosition(element) {
    var xPosition = 0,
    yPosition = 0;

    while (element) {
        xPosition += (element.offsetLeft
            + element.clientLeft);
        yPosition += (element.offsetTop
            + element.clientTop);
        element = element.offsetParent;
    }
    return {x: xPosition, y: yPosition};
}

Math.easeInOutQuad = function (time, start, change, duration) {
    time /= duration / 2;
    if (time < 1) {
        return change / 2 * time * time + start;
    }
    time--;
    return -change / 2 * (time * (time - 2) - 1) + start;
};

function scrollTo(element, to, duration) {
    var start = element.scrollTop,
    change = to - start,
    currentTime = 0,
    increment = 1;

    var animateScroll = function() {
        var val = Math.easeInOutQuad(currentTime, start, change, duration);
        element.scrollTop = val;
        currentTime += increment;
        if (currentTime <= duration) {
            setTimeout(animateScroll, increment);
        }
    };

    animateScroll();
}

function scrollToNext(context, collection, dir) {
    var item,
    i = 0;

    switch (dir) {
        case 'up':
            for (i = collection.length - 1; i >= 0; i--) {
                item = collection[i];

                if (getPosition(item).y < context.scrollTop - 2) {
                    scrollTo(context, getPosition(item).y, 30);
                    break;
                }
            }
        break;
        case 'down':
        default:
            for (i = 0; i < collection.length; i++) {
                item = collection[i];

                if (getPosition(item).y > context.scrollTop + 2) {
                    scrollTo(context, getPosition(item).y, 30);
                    break;
                }
            }
        break;
    }
}

// Trigger in keydown handler
if (event.keyCode === shortcuts['next_post'] && checkModifiers('next_post', event, shortcuts)) {
    event.preventDefault();
    scrollToNext(document.body, document.getElementsByClassName('post_block'), 'down');
} else if (event.keyCode === shortcuts['previous_post'] && checkModifiers('previous_post', event, shortcuts)) {
    event.preventDefault();
    scrollToNext(document.body, document.getElementsByClassName('post_block'), 'up');
}

Any ideas on what's wrong?


Solution

  • Found it. Firefox uses document.documentElement for its scrolling while Chrome uses document.body.

    I had to use both to get it to work in all browsers.