1
0
mirror of https://github.com/locomotivemtl/locomotive-boilerplate.git synced 2026-01-15 00:55:08 +08:00

Create tickers and events utils

This commit is contained in:
Lucas Vallenet
2022-06-02 16:26:29 +02:00
parent c8d4e7c154
commit 99291b17f5
5 changed files with 271 additions and 3711 deletions

View File

@@ -1,15 +0,0 @@
export default function(func, wait, immediate) {
let timeout;
return function() {
const context = this;
const args = arguments;
const later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}

View File

@@ -0,0 +1,206 @@
import { debounce } from './tickers'
CUSTOM_EVENT_LISTENERS = []
/**
* Check if element is Window
* @param {DOMElement} $el - Element to check
* @return {boolean} True if window
*/
const isWindow = $el => $el === window
/**
* Check if element is a DOM element
* @param {DOMElement} $el - Element to check
* @return {boolean} True if dom element
*/
const isDomElement = $el => ($el instanceof Element || $el instanceof HTMLDocument || $el instanceof HTMLDocument)
/**
* Check if element is Window or DOM element
* @param {Element} $el - Element to check
* @return {boolean} True if window or DOM element
*/
const isValidElement = $el => (isWindow($el) || isDomElement($el))
/**
* Check if element already has the event attached
* @param {Element} $el - Element where the event is attached
* @param {String} event - The event name
* @return {Boolean} True if the event is already attached to the element
*/
const customEventIsDefined = ($el, event) => CUSTOM_EVENT_LISTENERS.findIndex(e => e.$el === $el && e.event === event) > -1
/**
* Add custom event to event storage
* @param {Element} $el - Element where the event is attached
* @param {String} event - The event name
* @return {void}
*/
const addCustomEvent = ($el, event) => {
if(!customEventIsDefined($el, event)) {
CUSTOM_EVENT_LISTENERS.push({
$el,
event
})
}
}
/**
* Create a sarting event for the event triggered
* @param {Element} EventTarget - Element to bind the event to
* @param {object} event - The triggered event's name
* @return {void}
*/
const addStartEvent = (EventTarget, event, delay = 200) => {
const eventName = `${event}Start`
// Check element
if(!isValidElement(EventTarget)) {
console.warn(`[addStartEvent:${eventName}]: Wrong parameter '${el}'. The parameter must be document, window or a DOM element`)
return
}
// Check if event already exists
if(customEventIsDefined(EventTarget, eventName)) {
console.log(`[addStartEvent:${eventName}]: Already exists for '${el}' element`)
return
}
// Register element and event
addCustomEvent(EventTarget, eventName)
// Create event
const startEvent = new CustomEvent(eventName)
EventTarget.addEventListener(event, debounce(() => {
EventTarget.dispatchEvent(startEvent)
}, delay, true))
}
/**
* Create an ending event for the event triggered
* @param {Element} EventTarget - Element to bind the event to
* @param {object} event - The triggered event's name
* @return {void}
*/
const addEndEvent = (EventTarget, event, delay = 200) => {
const eventName = `${event}End`
// Check element
if(!isValidElement(EventTarget)) {
console.warn(`[addEndEvent:${eventName}]: Wrong parameter '${el}'. The parameter must be document, window or a DOM element`)
return
}
// Check if event already exists
if(customEventIsDefined(EventTarget, eventName)) {
console.log(`[addEndEvent:${eventName}]: Already exists for '${el}' element`)
return
}
// Register element and event
addCustomEvent(EventTarget, eventName)
// Create event
const endEvent = new CustomEvent(eventName)
EventTarget.addEventListener(event, debounce(() => {
EventTarget.dispatchEvent(endEvent)
}, delay))
}
/**
* Add scrollUp event to element (window by default)
* @param {Element} EventTarget - Element to bind the event to
* @return {void}
*/
const addScrollUpEvent = (EventTarget = window) => {
// Check element
if(!isValidElement(EventTarget)) {
console.warn(`[addScrollUpEvent]: Wrong parameter '${el}'. The parameter must be window or a DOM element`)
return
}
let scrollTop = EventTarget.scrollTop
let previousScrollTop = scrollTop
let direction = 0
const scrollUp = new CustomEvent('scrollUp')
const scrollProperty = isWindow(EventTarget) ? 'scrollY' : 'scrollTop'
EventTarget.addEventListener('scroll', e => {
scrollTop = EventTarget[scrollProperty]
// Scroll up
if(scrollTop < previousScrollTop && direction > -1) {
EventTarget.dispatchEvent(scrollUp)
direction = -1
// Scroll down
} else if(scrollTop > previousScrollTop && direction < 1) {
direction = 1
}
previousScrollTop = scrollTop
})
}
/**
* Add scrollDown event to element (window by default)
* @param {Element} EventTarget - Element to bind the event to
* @return {void}
*/
const addScrollDownEvent = (EventTarget = window) => {
// Check element
if(!isValidElement(EventTarget)) {
console.warn(`[addScrollDownEvent]: Wrong parameter '${el}'. The parameter must be window or a DOM element`)
return
}
let scrollTop = EventTarget.scrollTop
let previousScrollTop = scrollTop
let direction = 0
const scrollDown = new CustomEvent('scrollDown')
const scrollProperty = isWindow(EventTarget) ? 'scrollY' : 'scrollTop'
EventTarget.addEventListener('scroll', e => {
scrollTop = EventTarget[scrollProperty]
// Scroll up
if(scrollTop < previousScrollTop && direction > -1) {
direction = -1
// Scroll down
} else if(scrollTop > previousScrollTop && direction < 1) {
EventTarget.dispatchEvent(scrollDown)
direction = 1
}
previousScrollTop = scrollTop
})
}
export {
addStartEvent,
addEndEvent,
addScrollUpEvent,
addScrollDownEvent,
}

View File

@@ -0,0 +1,58 @@
/**
* Debounce function: fire the callback before/after the action has finished for the defined amount of time
* @param {function} callback - callback function
* @param {number} delay - waiting time in milisecond
* @param {boolean} immediate - triggers before or after delay
* @return {function} callback
*/
const debounce = (callback, delay, immediate = false) => {
let timeout = null
return (...args) => {
clearTimeout(timeout)
const later = () => {
timeout = null
if (!immediate) {
callback(...args)
}
}
if (immediate && !timeout) {
callback(...args)
}
timeout = setTimeout(later, delay)
}
}
/**
* Throttle function: fire the callback while the action is being performed for the defined iteration time
* @param {function} callback - callback function
* @param {number} delay - waiting time in milisecond
* @return {function} callback
*/
const throttle = (callback, delay) => {
let timeout = false
return (...args) => {
if (!timeout) {
timeout = true
callback(...args)
setTimeout(() => {
timeout = false
}, delay)
}
}
}
export {
debounce,
throttle
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long