/** @license Copyright (c) 2022 trading_peter This program is available under Apache License Version 2.0 */ import { debounce } from '@tp/helpers/debounce.js'; import { LitElement, css } from 'lit'; class TpScrollThreshold extends LitElement { static get styles() { return [ css` :host { display: none; } ` ]; } static get properties() { return { target: { type: Object }, upperThreshold: { type: Number }, lowerThreshold: { type: Number }, upperTriggered: { type: Boolean }, lowerTriggered: { type: Boolean }, }; } constructor() { super(); this.onScroll = debounce(this.onScroll.bind(this), 200); this.upperThreshold = 0; this.lowerThreshold = 0; this.upperTriggered = false; this.lowerTriggered = false; } firstUpdated() { if (!this.target) { console.error(this.tagname + ': Missing scroll target'); return } this.target.addEventListener('scroll', this.onScroll, { passive: true }); } onScroll() { this.checkScrollThresholds(); } checkScrollThresholds() { if (this.lowerTriggered && this.upperTriggered) { return; } const upperScrollValue = this.horizontal ? this._scrollLeft : this._scrollTop; const lowerScrollValue = this.horizontal ? this.target.scrollWidth - this._targetWidth - this._scrollLeft : this.target.scrollHeight - this._targetHeight - this._scrollTop; // Detect upper threshold if (upperScrollValue <= this.upperThreshold && !this.upperTriggered) { this.upperTriggered = true; this.dispatchEvent(new CustomEvent('upper-threshold', { detail: null, bubbles: true, composed: true })); } // Detect lower threshold if (lowerScrollValue <= this.lowerThreshold && !this.lowerTriggered) { this.lowerTriggered = true; this.dispatchEvent(new CustomEvent('lower-threshold', { detail: null, bubbles: true, composed: true })); } } clearTriggers() { this.upperTriggered = false; this.lowerTriggered = false; } get _doc() { return this.ownerDocument.documentElement; } get _scrollTop() { return this.target === this._doc ? window.pageYOffset : this.target.scrollTop; } get _scrollLeft() { return this.target === this._doc ? window.pageXOffset : this.target.scrollLeft; } get _targetWidth() { return this.target === this._doc ? window.innerWidth : this.target.offsetWidth; } get _targetHeight() { return this.target === this._doc ? window.innerHeight : this.target.offsetHeight; } } window.customElements.define('tp-scroll-threshold', TpScrollThreshold);