@roderickhsiao/react-i13n
Version:
[Experiment] React I13n provides a performant and scalable solution to application instrumentation.
119 lines (99 loc) • 3.44 kB
JavaScript
"use strict";
exports.__esModule = true;
exports["default"] = void 0;
var _subscribeUiEvent = require("subscribe-ui-event");
/**
* Copyright 2015 - Present, Yahoo Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var SUBSCRIBE_OPTIONS = {
enableScrollInfo: true
};
var DEFAULT_VIEWPORT_MARGINS = {
usePercent: false,
top: 20,
bottom: 20
};
/**
* Viewport Detector
* @param {Object} element DOM element to detect
* @param {Object} [options] options object
* @param {Object} [options.margins] viewport detection margin setting
* @param {Object} [options.margins.top] viewport top margin setting
* @param {Object} [options.margins.bottom] viewport bottom margin setting
* @param {Object} [options.margins.usePercent] true to use top and bottom as percentage instead of pixel
* @param {Object} [options.target] target of ui events, should be a dom element
* @param {Function} onEnterViewport callback when the DOM element enters the viewport
* @constructor
*/
var ViewportDetector = function ViewportDetector(element, options, onEnterViewport) {
var marginOptions = options && options.margins || DEFAULT_VIEWPORT_MARGINS;
var clientHeight = window.innerHeight;
this._element = element;
this._onEnterViewport = onEnterViewport;
this._subscribers = [];
this._rect;
this._margins = {
top: marginOptions.usePercent ? marginOptions.top * clientHeight : marginOptions.top,
bottom: marginOptions.usePercent ? marginOptions.bottom * clientHeight : marginOptions.bottom
};
this._options = Object.assign({}, SUBSCRIBE_OPTIONS);
if (options.target) {
this._options.target = options.target;
}
this._enteredViewport = false;
};
/**
* Detect viewport
* @method _detectViewport
* @returns {void}
* @private
*/
ViewportDetector.prototype._detectViewport = function () {
var _window = window,
innerHeight = _window.innerHeight;
if (!this._element) {
return this._onEnterViewport && this._onEnterViewport();
}
var rect = this._element.getBoundingClientRect(); // Detect Screen Bottom // Detect Screen Top
if (rect.top < innerHeight + this._margins.top && rect.bottom > 0 - this._margins.bottom) {
this._enteredViewport = true;
this.unsubscribeAll();
this._onEnterViewport && this._onEnterViewport();
}
};
/**
* Initialize the viewport detection
* @method init
* @param {Boolean} skipInitDetection skip the init detection
* @returns {void}
*/
ViewportDetector.prototype.init = function (skipInitDetection) {
// detect viewport and execute handler if it's initially in the viewport
if (!skipInitDetection) {
this._detectViewport();
}
if (!this._enteredViewport) {
this._subscribers = [(0, _subscribeUiEvent.subscribe)('scrollEnd', this._detectViewport.bind(this), this._options)];
}
};
/**
* unsubscribe all ui event listeners
* @method unsubscribeAll
* @returns {void}
*/
ViewportDetector.prototype.unsubscribeAll = function () {
this._subscribers.forEach(function (subscriber) {
subscriber.unsubscribe();
});
};
/**
* Return the value if the element already entered the viewport
* @method isEnteredViewport
* @returns {Boolean} true if the element entered the viewport
*/
ViewportDetector.prototype.isEnteredViewport = function () {
return this._enteredViewport;
};
var _default = ViewportDetector;
exports["default"] = _default;