seng-scroll-tracker
Version:
Class that keeps track of the vertical scroll position of an element.
145 lines (144 loc) • 6.47 kB
JavaScript
"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;