UNPKG

organism-react-scroll-nav

Version:
318 lines 10 kB
import _objectSpread from "reshow-runtime/es/helpers/objectSpread2"; import _classCallCheck from "reshow-runtime/es/helpers/classCallCheck"; import _createClass from "reshow-runtime/es/helpers/createClass"; import _defineProperty from "reshow-runtime/es/helpers/defineProperty"; import { mergeMap, Set, Map, ImmutableStore } from "reshow-flux"; import getScrollInfo from "get-scroll-info"; import { isOnScreen } from "get-window-offset"; import _getOffset from "getoffset"; import get from "get-object-value"; import callfunc, { debounce } from "call-func"; import { win } from "win-doc"; import query from "css-query-selector"; import testForPassiveScroll from "../testForPassiveScroll.mjs"; var incNum = 0; var DEFAULT_SCROLL_ID = -1; var Scroller = /*#__PURE__*/function () { function Scroller() { _classCallCheck(this, Scroller); _defineProperty(this, "storeName", "delayScroll"); _defineProperty(this, "isInitResizeEvent", false); _defineProperty(this, "checkIsActive", function (scrollTop, pos) { return scrollTop >= pos.top - 1 && scrollTop <= pos.bottom - 2; }); } return _createClass(Scroller, [{ key: "initResizeEvent", value: function initResizeEvent() { var oWin = win(); if (!oWin.__null) { this.isInitResizeEvent = true; if (oWin.addEventListener) { oWin.addEventListener("resize", this.bindHandleResize); } else { oWin.attachEvent("onresize", this.bindHandleResize); } } } }, { key: "initEvent", value: function initEvent(el, retry) { var _this = this; if ("undefined" !== typeof el) { if (el.addEventListener) { var supportsPassive = testForPassiveScroll(); el.addEventListener("scroll", this.scrollMonitor, supportsPassive ? { passive: true } : false); } else { el.attachEvent("onscroll", this.scrollMonitor); } var i = 0; this.clearInitTimer(); this.initTimer = setInterval( //for lazy content function () { _this.trigger(el); i++; if (i > retry) { _this.clearInitTimer(); } }, 300); if (!this.isInitResizeEvent) { this.initResizeEvent(); } } } }, { key: "removeEvent", value: function removeEvent(el) { if (el !== null && el !== void 0 && el.removeEventListener) { el.removeEventListener("scroll", this.scrollMonitor); } else { el === null || el === void 0 || el.deachEvent("onscroll", this.scrollMonitor); } } }, { key: "handleResize", value: function handleResize() { var _this2 = this; this.spys.keySeq().forEach(function (scrollId) { _this2.scrollMonitor({ target: { id: scrollId } }); }); } }, { key: "runScrollMonitor", value: function runScrollMonitor(e) { var delay = this.store.getState().get("scrollDelay"); this.scrollDebounce({ delay, args: [e === null || e === void 0 ? void 0 : e.target] }); } }, { key: "triggerScroll", value: function triggerScroll(scrollNode) { var _this3 = this; var scrollId = get(scrollNode, ["id"]) || DEFAULT_SCROLL_ID; var defaultMargin = this.store.getState().get("scrollMargin"); var actives = { mdefault: null }; var offsetCache = {}; var allMonitorNode = []; var scroll = getScrollInfo(); var scrollTop = scroll.top + defaultMargin; (this.spys.get(scrollId) || []).forEach(function (node) { var nodeEl = node.getOffsetEl(); if (!nodeEl) { return; } var nodeId = _this3.getNodeId(node); var monitorScroll = callfunc(node.getMonitorScroll); var scrollMargin = callfunc(node.getScrollMargin); var pos = _getOffset(nodeEl); if (monitorScroll) { var isActive = _this3.checkIsActive(scrollTop, pos); if (isActive) { actives.mdefault = nodeId; } allMonitorNode.unshift(node); } var margin = scrollMargin ? scrollMargin : defaultMargin; pos = isOnScreen(pos, scroll, margin); offsetCache[nodeId] = pos; }); var allMonitorNodeLen = allMonitorNode.length; this.margins.forEach(function (margin) { var scrollTop = scroll.top + margin; actives["m" + margin] = null; var i = allMonitorNodeLen; while (i--) { var node = allMonitorNode[i]; var nodeId = _this3.getNodeId(node); var pos = offsetCache[nodeId]; var isActive = _this3.checkIsActive(scrollTop, pos); if (isActive) { actives["m" + margin] = nodeId; break; } } }); this.margins = this.margins.clear(); this.dispatch(_objectSpread(_objectSpread({}, actives), {}, { offsetCache, scroll, storeName: this.storeName })); } }, { key: "getOffset", value: function getOffset(id) { var offset = get(this.store.getMap("offsetCache"), [id]); if (offset && offset.h && offset.w) { return offset; } else { var node = this.getNode(id) || {}; var dom = callfunc(node.getOffsetEl) || query.one("#" + id); var domOffset = dom && _getOffset(dom); if (domOffset) { var scrollInfo = getScrollInfo(); var defaultMargin = this.store.getState().get("scrollMargin"); var margin = callfunc(node.getScrollMargin) || defaultMargin; domOffset = isOnScreen(domOffset, scrollInfo, margin); return domOffset; } else { return offset; } } } }, { key: "hasAttach", value: function hasAttach(node) { var attachDestId = this.getAttachDestId(node); var attachDest = this.spys.get(attachDestId); if (attachDest && attachDest.has(node)) { return attachDestId; } else { return false; } } }, { key: "getNodeId", value: function getNodeId(node) { var id = callfunc(node.getId) || node.id; if (!id) { if (node === win()) { return DEFAULT_SCROLL_ID; } else { return this.setNodeId(node); } } else { return id; } } }, { key: "setNodeId", value: function setNodeId(node) { var nextId = "spy-" + incNum; incNum++; if (node.setId) { node.setId(nextId); } else { node.id = nextId; } return nextId; } }, { key: "getAttachDestId", value: function getAttachDestId(node) { var attachDest = callfunc(node.getAttachDest); var attachDestId; if (attachDest) { attachDestId = this.getNodeId(attachDest); } else { var oWin = win(); if (!oWin.__null) { node.setAttachDest(oWin); } attachDestId = DEFAULT_SCROLL_ID; } return attachDestId; } }, { key: "getNode", value: function getNode(nodeId) { var node = this.arrNode.get(nodeId); return node; } }, { key: "attach", value: function attach(node) { var nodeId = this.getNodeId(node); /** * if not set attachDest, the default attachDest is window. */ var attachDestId = this.getAttachDestId(node); var attachDest = this.spys.get(attachDestId); if (!attachDest) { this.spys = this.spys.set(attachDestId, Set().add(node)); } else { this.spys = this.spys.set(attachDestId, attachDest.add(node)); } this.arrNode = this.arrNode.set(nodeId, node); if (!this.isInitEvent.get(attachDestId)) { this.isInitEvent = this.isInitEvent.set(attachDestId, true); this.initEvent(callfunc(node.getAttachDest), callfunc(node.getAttachDestRetry)); } return nodeId; } }, { key: "detach", value: function detach(node) { var attachDestId = this.hasAttach(node); if (attachDestId) { this.spys = this.spys.set(attachDestId, this.spys.get(attachDestId).remove(node)); this.arrNode = this.arrNode.delete(this.getNodeId(node)); if (!this.spys.get(attachDestId).size) { this.removeEvent(node.attachDestId); this.spys = this.spys.delete(attachDestId); this.isInitEvent = this.isInitEvent.delete(attachDestId); } } } }, { key: "addMargin", value: function addMargin(num) { this.margins = this.margins.add(num); } }, { key: "deleteMargin", value: function deleteMargin(num) { this.margins = this.margins.remove(num); } }, { key: "clearInitTimer", value: function clearInitTimer() { if (this.initTimer) { clearInterval(this.initTimer); this.initTimer = null; } } }, { key: "getInitialState", value: function getInitialState() { this.initTimer = null; this.trigger = this.triggerScroll.bind(this); this.isInitEvent = Map(); this.spys = Map(); this.arrNode = Map(); this.margins = Set(); this.scrollMonitor = this.runScrollMonitor.bind(this); this.scrollDebounce = debounce(this.trigger); this.bindHandleResize = this.handleResize.bind(this); return Map({ scrollDelay: 50, scrollMargin: 0 }); } }, { key: "reduce", value: function reduce(state, action) { return mergeMap(state, action); } }]); }(); var oDelayScroller = new Scroller(); var [store, delayScrollDispatch] = ImmutableStore(oDelayScroller.reduce.bind(oDelayScroller), oDelayScroller.getInitialState.bind(oDelayScroller)); var scrollStore = _objectSpread(_objectSpread({}, store), {}, { scroller: oDelayScroller }); oDelayScroller.dispatch = delayScrollDispatch; oDelayScroller.store = store; export default scrollStore; export { Scroller };