organism-react-scroll-nav
Version:
A React scroll spy library with flux
325 lines (324 loc) • 11.4 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("reshow-runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("reshow-runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports["default"] = exports.Scroller = void 0;
var _objectSpread2 = _interopRequireDefault(require("reshow-runtime/helpers/objectSpread2"));
var _classCallCheck2 = _interopRequireDefault(require("reshow-runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("reshow-runtime/helpers/createClass"));
var _defineProperty2 = _interopRequireDefault(require("reshow-runtime/helpers/defineProperty"));
var _reshowFlux = require("reshow-flux");
var _getScrollInfo = _interopRequireDefault(require("get-scroll-info"));
var _getWindowOffset = require("get-window-offset");
var _getoffset = _interopRequireDefault(require("getoffset"));
var _getObjectValue = _interopRequireDefault(require("get-object-value"));
var _callFunc = _interopRequireWildcard(require("call-func"));
var _winDoc = require("win-doc");
var _cssQuerySelector = _interopRequireDefault(require("css-query-selector"));
var _testForPassiveScroll = _interopRequireDefault(require("../testForPassiveScroll.js"));
var incNum = 0;
var DEFAULT_SCROLL_ID = -1;
var Scroller = exports.Scroller = /*#__PURE__*/function () {
function Scroller() {
(0, _classCallCheck2["default"])(this, Scroller);
(0, _defineProperty2["default"])(this, "storeName", "delayScroll");
(0, _defineProperty2["default"])(this, "isInitResizeEvent", false);
(0, _defineProperty2["default"])(this, "checkIsActive", function (scrollTop, pos) {
return scrollTop >= pos.top - 1 && scrollTop <= pos.bottom - 2;
});
}
return (0, _createClass2["default"])(Scroller, [{
key: "initResizeEvent",
value: function initResizeEvent() {
var oWin = (0, _winDoc.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 = (0, _testForPassiveScroll["default"])();
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: delay,
args: [e === null || e === void 0 ? void 0 : e.target]
});
}
}, {
key: "triggerScroll",
value: function triggerScroll(scrollNode) {
var _this3 = this;
var scrollId = (0, _getObjectValue["default"])(scrollNode, ["id"]) || DEFAULT_SCROLL_ID;
var defaultMargin = this.store.getState().get("scrollMargin");
var actives = {
mdefault: null
};
var offsetCache = {};
var allMonitorNode = [];
var scroll = (0, _getScrollInfo["default"])();
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 = (0, _callFunc["default"])(node.getMonitorScroll);
var scrollMargin = (0, _callFunc["default"])(node.getScrollMargin);
var pos = (0, _getoffset["default"])(nodeEl);
if (monitorScroll) {
var isActive = _this3.checkIsActive(scrollTop, pos);
if (isActive) {
actives.mdefault = nodeId;
}
allMonitorNode.unshift(node);
}
var margin = scrollMargin ? scrollMargin : defaultMargin;
pos = (0, _getWindowOffset.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((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, actives), {}, {
offsetCache: offsetCache,
scroll: scroll,
storeName: this.storeName
}));
}
}, {
key: "getOffset",
value: function getOffset(id) {
var offset = (0, _getObjectValue["default"])(this.store.getMap("offsetCache"), [id]);
if (offset && offset.h && offset.w) {
return offset;
} else {
var node = this.getNode(id) || {};
var dom = (0, _callFunc["default"])(node.getOffsetEl) || _cssQuerySelector["default"].one("#" + id);
var domOffset = dom && (0, _getoffset["default"])(dom);
if (domOffset) {
var scrollInfo = (0, _getScrollInfo["default"])();
var defaultMargin = this.store.getState().get("scrollMargin");
var margin = (0, _callFunc["default"])(node.getScrollMargin) || defaultMargin;
domOffset = (0, _getWindowOffset.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 = (0, _callFunc["default"])(node.getId) || node.id;
if (!id) {
if (node === (0, _winDoc.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 = (0, _callFunc["default"])(node.getAttachDest);
var attachDestId;
if (attachDest) {
attachDestId = this.getNodeId(attachDest);
} else {
var oWin = (0, _winDoc.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, (0, _reshowFlux.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((0, _callFunc["default"])(node.getAttachDest), (0, _callFunc["default"])(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 = (0, _reshowFlux.Map)();
this.spys = (0, _reshowFlux.Map)();
this.arrNode = (0, _reshowFlux.Map)();
this.margins = (0, _reshowFlux.Set)();
this.scrollMonitor = this.runScrollMonitor.bind(this);
this.scrollDebounce = (0, _callFunc.debounce)(this.trigger);
this.bindHandleResize = this.handleResize.bind(this);
return (0, _reshowFlux.Map)({
scrollDelay: 50,
scrollMargin: 0
});
}
}, {
key: "reduce",
value: function reduce(state, action) {
return (0, _reshowFlux.mergeMap)(state, action);
}
}]);
}();
var oDelayScroller = new Scroller();
var _ImmutableStore = (0, _reshowFlux.ImmutableStore)(oDelayScroller.reduce.bind(oDelayScroller), oDelayScroller.getInitialState.bind(oDelayScroller)),
store = _ImmutableStore[0],
delayScrollDispatch = _ImmutableStore[1];
var scrollStore = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, store), {}, {
scroller: oDelayScroller
});
oDelayScroller.dispatch = delayScrollDispatch;
oDelayScroller.store = store;
var _default = exports["default"] = scrollStore;