Shoora
4/29/2019 - 2:08 PM

track "start reading", "stop reading", "end reading" user events on articles

track "start reading", "stop reading", "end reading" user events on articles

class ArticleScrollSpy {
    constructor(params = {
        debugMode: false, 
        callBackTime: 100, // Default time delay before checking location
        readerLocation: 150, // # px before tracking a reader
        wordsPerMinute: 270,
    }) {
        this.debugMode = params.debugMode;
        this.callBackTime = params.callBackTime; 
        this.readerLocation = params.readerLocation;
        this.wordsPerMinute = params.wordsPerMinute;
        this.el_content = params.el_content;

        this.onLoad();
        this.addEventListeners();
    }

    timer = 0;
    beginning = Date.now();
    
    startScroll = false;
    endContent = false;
    didComplete = false;

    get timeToScroll() {
        return Math.round((Date.now() - this.beginning) / 1000);
    }

    get pageBottom() {
        return window.innerHeight + window.scrollY;
    }

    get pageHeight() {
        return document.body.clentHeight;
    }

    get contentHeight() {
        return this.el_content.offsetHeight + this.el_content.offsetTop;
    }
    
    get contentWordsCount() {
        return this.el_content.textContent.trim().split(/\s+/g).filter(word => word.length > 2).length;
    }

    addEventListeners() {
        window.addEventListener('scroll', ::this.onScroll, false);
    }

    onLoad() {
        this.sendGaEvent('Loaded');
    }

    onScroll() {
        timer && clearTimeout(timer);
        timer = setTimeout(() => { requestAnimationFrame(::this.trackLocation) }, this.callBackTime);
    }

    trackLocation() {
        if (!this.startScroll && this.bottom > this.readerLocation) { // on scroll start
            this.sendGaEvent('start', this.timeToScroll);
            this.startScroll = true;
        }
        else if (!this.didComplete && this.pageBottom >= this.pageHeight) { // on page bottom
            this.sendGaEvent('endPage', this.timeToScroll);
            this.sendGaEvent(this.timeToScroll < 60 ? 'Scanner' : 'Reader');
            this.didComplete = true;
        }
        else if (!this.endContent && this.pageBottom >= this.contentHeight) { // on content bottom
            this.sendGaEvent('endContent');
            this.endContent = true;
        }
    }

    sendGaEvent(...params) {
        if (!debugMode) {
            ga('send', 'event', 'News', 'Article', ...params);
        } else {
            console.log(...params);    
        }
    }
}