All files scroll-spy.js

48.39% Statements 15/31
12.5% Branches 2/16
11.11% Functions 1/9
48.39% Lines 15/31
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79      1x 1x 1x       1x 1x 1x     1x       1x 1x                                                             1x 1x   1x                     1x 1x   1x                      
/**
 * The class responsible for keeping track of scrolling
 */
import ReactDOM from 'react-dom';
import { throttle } from './utils';
import Scroller from './scroller';
 
class ScrollSpy {
    constructor() {
        this._linksRegister = [];
        this._scrollPanelRegister = [];
        window.addEventListener('scroll', throttle(() =>
            this._handleScroll({ target: document.body }))
        );
        this._handleScroll({ target: document.body });
    }
 
    registerLink(component) {
        Eif (!this._linksRegister.includes(component)) {
            this._linksRegister.push(component);
        }
    }
 
    registerScrollpanel(component) {
        if (!this._scrollPanelRegister.includes(component)) {
            const listener = throttle(this._handleScroll.bind(this));
            component.addEventListener('scroll', listener);
            this._handleScroll({ target: component });
            this._scrollPanelRegister.push({ component, listener });
        }
    }
 
    unregisterLink(component) {
        const index = this._linksRegister.indexOf(component);
        if (index >= 0) {
            this._linksRegister.splice(index, 1);
        }
    }
 
    unregisterScrollpanel(component) {
        const index = this._scrollPanelRegister.findIndex((el) => el.component === component);
        if (index >= 0) {
            const el = this._scrollPanelRegister[index];
            el.component.removeEventListener('scroll', el.listener);
 
            this._scrollPanelRegister.splice(index, 1);
        }
    }
 
    _handleScroll(e) {
        const scrolledIn = e.target;
        const scrollOffset = scrolledIn.scrollTop;
 
        const elements = this._linksRegister
            .map((link) => ({ link, href: link.props.href }))
            .map(({ link, href }) => ({
                link, href,
                panelComp: Scroller.getElementPanel(href),
                panel: ReactDOM.findDOMNode(Scroller.getElementPanel(href))
            }))
            .filter(({ panel }) => scrolledIn.contains(panel))
            .map(({ link, panelComp, panel }) => link._handleScroll(scrollOffset, scrolledIn, { panel, panelComp }));
 
 
        const newActive = elements.find(({ isInside, hasActive }) => isInside && !hasActive);
        const oldActive = elements.find(({ isInside, hasActive }) => !isInside && hasActive);
 
        Iif (newActive) {
            newActive.link.classList.add(newActive.activeClass);
 
            if (oldActive) {
                oldActive.link.classList.remove(oldActive.activeClass);
            }
        }
    }
}
 
export default new ScrollSpy();