UNPKG

seng-scroll-tracker

Version:

Class that keeps track of the vertical scroll position of an element.

145 lines (144 loc) 6.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var seng_event_1 = require("seng-event"); var Side_1 = require("./enum/Side"); var ScrollTrackerEvent_1 = require("./event/ScrollTrackerEvent"); /** * Instance created for every coordinate that a ScrollTracker tracks. */ var ScrollTrackerPoint = /** @class */ (function (_super) { tslib_1.__extends(ScrollTrackerPoint, _super); function ScrollTrackerPoint(scrollPosition, pointHeight, pointSide, pointTracker) { var _this = _super.call(this) || this; _this.scrollPosition = scrollPosition; _this.pointHeight = pointHeight; _this.pointSide = pointSide; _this.pointTracker = pointTracker; /** * Boolean indicating if the point is currently in view. Updated when checkInView() is called. */ _this.isInView = false; /** * Boolean indicating if the point is currently within the bounds of the target element. * Updated when checkInView() is called. */ _this.isInBounds = false; /** * Boolean indicating if the top of the viewport has been scrolled beyond this point */ _this.hasScrolledBeyond = false; setTimeout(function () { if (_this.isDisposed()) { return; } _this.checkScrollBeyond(); _this.isInView = _this.getInViewValue(); }, 0); return _this; } Object.defineProperty(ScrollTrackerPoint.prototype, "position", { /** * @returns {number} The current position of the point in pixels. This is the distance from the * start or end of the target element depending on the 'side' parameter, measured horizontally or * vertically depending on the axis of this ScrollTracker instance. */ get: function () { return this.scrollPosition; }, /** * Change the position of this point. Executes checkInView to check if the point has entered or * leaved view. * @param position The position of this points in pixels. This is the distance from the start * or end of the target element depending on the 'side' parameter, measured horizontally or * vertically depending on the axis of this ScrollTracker instance. */ set: function (position) { this.scrollPosition = position; this.checkInView(); }, enumerable: true, configurable: true }); Object.defineProperty(ScrollTrackerPoint.prototype, "height", { /** * @returns {number} The current height of the point in pixels. This is the distance from the * start or end of the target element depending on the 'side' parameter, measured horizontally or * vertically depending on the axis of this ScrollTracker instance. */ get: function () { return this.pointHeight; }, /** * Change the height of this point. Executes checkInView to check if the point has entered or * leaved view. * @param height The height of this points in pixels. This is the distance from the start * or end of the target element depending on the 'side' parameter, measured horizontally or * vertically depending on the axis of this ScrollTracker instance. */ set: function (height) { this.pointHeight = height; this.checkInView(); }, enumerable: true, configurable: true }); Object.defineProperty(ScrollTrackerPoint.prototype, "side", { /** * @returns {Side} The side of from which the position of this point is measured. */ get: function () { return this.pointSide; }, enumerable: true, configurable: true }); ScrollTrackerPoint.prototype.getInViewValue = function () { var viewEnd = this.pointTracker.viewEnd; // pageYOffset + windowHeight return viewEnd >= this.scrollPosition && viewEnd <= this.scrollPosition + this.pointHeight + window.innerHeight; }; ScrollTrackerPoint.prototype.checkScrollBeyond = function () { var positionFromStart = this.pointSide === Side_1.default.START ? this.scrollPosition : this.pointTracker.scrollSize - this.scrollPosition; if (!this.hasScrolledBeyond) { var hasScrolledBeyond = this.pointTracker.viewEnd >= positionFromStart; if (hasScrolledBeyond) { this.hasScrolledBeyond = true; } } }; /** * Checks if this point is in view using it's position and the current scroll position saved on * the ScrollTracker. Updates the isInView property accordingly. * @return {boolean} True if this point is in view. */ ScrollTrackerPoint.prototype.checkInView = function (scrollingBack) { if (scrollingBack === void 0) { scrollingBack = false; } var isInView = this.getInViewValue(); this.isInBounds = this.scrollPosition >= 0 && this.scrollPosition <= this.pointTracker.viewEnd; var positionFromStart = this.pointSide === Side_1.default.START ? this.scrollPosition : this.pointTracker.scrollSize - this.scrollPosition; if (this.isInView !== isInView) { this.isInView = isInView; var eventType = isInView ? ScrollTrackerEvent_1.default.types.ENTER_VIEW : ScrollTrackerEvent_1.default.types.LEAVE_VIEW; var event_1 = new ScrollTrackerEvent_1.default(eventType, this, (isInView ? scrollingBack : !scrollingBack) ? Side_1.default.START : Side_1.default.END); this.dispatchEvent(event_1); } if (!this.hasScrolledBeyond && this.pointTracker.viewEnd >= positionFromStart && !isInView) { this.hasScrolledBeyond = true; this.dispatchEvent(new ScrollTrackerEvent_1.default(ScrollTrackerEvent_1.default.types.SCROLLED_BEYOND, this, Side_1.default.END)); } return this.isInView; }; /** * Disposes the ScrollTrackerPoint instance. */ ScrollTrackerPoint.prototype.dispose = function () { this.pointTracker = null; _super.prototype.dispose.call(this); }; return ScrollTrackerPoint; }(seng_event_1.default)); exports.default = ScrollTrackerPoint;