UNPKG

shineout

Version:

Shein 前端组件库

445 lines (371 loc) 17.8 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = exports.BAR_WIDTH = void 0; var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireDefault(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _scrollBehavior = require("../utils/dom/scrollBehavior"); var _component = require("../component"); var _element = require("../utils/dom/element"); var _normalizeWheel = _interopRequireDefault(require("../utils/dom/normalizeWheel")); var _styles = require("./styles"); var _Bar = _interopRequireDefault(require("./Bar")); var _config = _interopRequireWildcard(require("../config")); var _context = require("./context"); var _lazyload = require("../utils/lazyload"); var BAR_WIDTH = 16; exports.BAR_WIDTH = BAR_WIDTH; var Scroll = /*#__PURE__*/ function (_PureComponent) { (0, _inheritsLoose2.default)(Scroll, _PureComponent); function Scroll(props) { var _this; _this = _PureComponent.call(this, props) || this; (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "baseScrollRatio", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "touchStartX", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "touchStartY", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "wheelX", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "wheelY", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "pixelX", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "pixelY", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "cacheWidth", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "cacheHeight", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "wheelElement", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "inner", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "footerElement", void 0); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), "rmOverScrollListener", void 0); _this.touchStartX = 0; _this.touchStartY = 0; _this.wheelX = props.scrollX; _this.wheelY = props.scrollY; _this.pixelX = 0; _this.pixelY = 0; _this.cacheWidth = 0; _this.cacheHeight = 0; _this.bindInner = _this.bindInner.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.bindWheel = _this.bindWheel.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.bindFooter = _this.bindFooter.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.setRect = _this.setRect.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleScrollX = _this.handleScrollX.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleScrollY = _this.handleScrollY.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleWheel = _this.handleWheel.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.bindIframe = _this.bindIframe.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleTouchStart = _this.handleTouchStart.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleTouchMove = _this.handleTouchMove.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.setStartPoint = _this.setStartPoint.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); _this.handleInnerScroll = _this.handleInnerScroll.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this))); return _this; } var _proto = Scroll.prototype; _proto.componentDidMount = function componentDidMount() { _PureComponent.prototype.componentDidMount.call(this); setTimeout(this.setRect); this.wheelElement.addEventListener('wheel', this.handleWheel, { passive: false }); this.wheelElement.addEventListener('touchstart', this.handleTouchStart, { passive: true }); this.wheelElement.addEventListener('touchmove', this.handleTouchMove, { passive: false }); this.inner.addEventListener('scroll', this.handleInnerScroll); this.wheelElement.addEventListener('scroll', this.handleInnerScroll); this.rmOverScrollListener = (0, _scrollBehavior.banOverScrollX)(this.wheelElement); }; _proto.componentDidUpdate = function componentDidUpdate(prevProps) { var _this$props = this.props, stable = _this$props.stable, scrollWidth = _this$props.scrollWidth, scrollHeight = _this$props.scrollHeight; if (scrollWidth !== prevProps.scrollWidth) this.setRect();else if (stable && scrollHeight !== prevProps.scrollHeight) this.setRect(); }; _proto.componentWillUnmount = function componentWillUnmount() { _PureComponent.prototype.componentWillUnmount.call(this); this.wheelElement.removeEventListener('wheel', this.handleWheel); this.wheelElement.removeEventListener('touchstart', this.handleTouchStart); this.wheelElement.removeEventListener('touchmove', this.handleTouchMove); this.inner.removeEventListener('scroll', this.handleInnerScroll); this.wheelElement.removeEventListener('scroll', this.handleInnerScroll); if (this.footerElement) { this.footerElement.removeEventListener('wheel', this.handleWheel); this.footerElement.removeEventListener('touchstart', this.handleTouchStart); this.footerElement.removeEventListener('touchmove', this.handleTouchMove); } if (this.rmOverScrollListener) this.rmOverScrollListener(); }; _proto.getWheelRect = function getWheelRect() { if (!this.wheelElement) return { width: 0, height: 0 }; var _this$wheelElement$ge = this.wheelElement.getBoundingClientRect(), width = _this$wheelElement$ge.width, height = _this$wheelElement$ge.height; // display none if (width === 0 && height === 0) { width = this.cacheWidth; height = this.cacheHeight; } else { this.cacheWidth = width; this.cacheHeight = height; } var _this$props2 = this.props, scrollX = _this$props2.scrollX, scrollY = _this$props2.scrollY, _this$props2$style = _this$props2.style, style = _this$props2$style === void 0 ? {} : _this$props2$style; width = (typeof style.width === 'number' ? style.width : width) - (scrollY ? BAR_WIDTH : 0); height = (typeof style.height === 'number' ? style.height : height) - (scrollX ? BAR_WIDTH : 0); return { width: width, height: height }; }; _proto.setRect = function setRect() { this.handleScroll(this.props.left, this.props.top); this.forceUpdate(); }; _proto.setBaseScrollHeightRatio = function setBaseScrollHeightRatio(height) { if (this.baseScrollRatio) return; this.baseScrollRatio = 1; var ratio = _config.default.scrollRatio; // windows scroll if (Math.abs(height) > 10) { this.baseScrollRatio = ratio / Math.abs(height); } }; _proto.setStartPoint = function setStartPoint(position) { this.touchStartX = position.clientX; this.touchStartY = position.clientY; }; _proto.bindInner = function bindInner(el) { this.inner = el; }; _proto.bindIframe = function bindIframe(el) { if (el && el.contentWindow) { el.contentWindow.onresize = (0, _lazyload.throttleWrapper)(this.setRect); } }; _proto.bindWheel = function bindWheel(el) { this.wheelElement = el; }; _proto.bindFooter = function bindFooter(el) { if (this.footerElement) { this.footerElement.removeEventListener('wheel', this.handleWheel); this.footerElement.removeEventListener('touchstart', this.handleTouchStart); this.footerElement.removeEventListener('touchmove', this.handleTouchMove); } if (el) { el.addEventListener('wheel', this.handleWheel, { passive: false }); el.addEventListener('touchstart', this.handleTouchStart, { passive: true }); el.addEventListener('touchmove', this.handleTouchMove, { passive: false }); } this.footerElement = el; }; _proto.boundleScroll = function boundleScroll() { /* this.locked = true this.scrollTimer = setTimeout(() => { this.locked = false if (this.pixelX !== 0 || this.pixelY !== 0) { this.boundleScroll() } }, 32) */ // lock direction if (Math.abs(this.pixelX) > Math.abs(this.pixelY)) { this.pixelY = 0; } else { this.pixelX = 0; } var _this$props3 = this.props, left = _this$props3.left, top = _this$props3.top; var _this$props4 = this.props, _this$props4$scrollWi = _this$props4.scrollWidth, scrollWidth = _this$props4$scrollWi === void 0 ? Scroll.defaultProps.scrollWidth : _this$props4$scrollWi, _this$props4$scrollHe = _this$props4.scrollHeight, scrollHeight = _this$props4$scrollHe === void 0 ? Scroll.defaultProps.scrollHeight : _this$props4$scrollHe; var x = left + this.pixelX / scrollWidth; if (x < 0) x = 0; if (x > 1) x = 1; var y = top + this.pixelY / scrollHeight; if (y < 0) y = 0; if (y > 1) y = 1; if (x !== left || y !== top) { this.handleScroll(x, y, this.pixelX, this.pixelY); } this.pixelX = 0; this.pixelY = 0; }; _proto.handleWheel = function handleWheel(event) { var scrollX = this.wheelX; var scrollY = this.wheelY; var _this$props$innerScro = this.props.innerScrollAttr, innerScrollAttr = _this$props$innerScro === void 0 ? Scroll.defaultProps.innerScrollAttr : _this$props$innerScro; if (!scrollX && !scrollY) return; var wheelTarget = event.target; if (innerScrollAttr.find(function (attr) { return wheelTarget.hasAttribute(attr); })) { event.stopPropagation(); return; } var target = (0, _element.getParent)(wheelTarget, "." + (0, _styles.scrollClass)('_')); var inFooter = false; if (this.footerElement) { inFooter = this.footerElement === event.target || this.footerElement.contains(wheelTarget); } if (target !== this.wheelElement && !inFooter) return; var wheel = (0, _normalizeWheel.default)(event); this.setBaseScrollHeightRatio(wheel.pixelY); if (scrollX) this.pixelX = (0, _config.isRTL)() ? this.pixelX - wheel.pixelX : this.pixelX + wheel.pixelX; if (scrollY && !inFooter) this.pixelY += wheel.pixelY * this.baseScrollRatio; if (Math.abs(wheel.pixelX) > Math.abs(wheel.pixelY)) { event.preventDefault(); } else if (scrollY) event.preventDefault(); // if (!this.locked) { this.boundleScroll(); // } }; _proto.handleScroll = function handleScroll(x, y, pixelX, pixelY, _temp) { var _ref = _temp === void 0 ? {} : _temp, drag = _ref.drag; var _this$props$scrollWid = this.props.scrollWidth, scrollWidth = _this$props$scrollWid === void 0 ? Scroll.defaultProps.scrollWidth : _this$props$scrollWid; var _this$getWheelRect = this.getWheelRect(), width = _this$getWheelRect.width, height = _this$getWheelRect.height; var max = Math.round((1 - width / scrollWidth) * scrollWidth); if (this.props.onScroll) { this.props.onScroll(x, y, max, this.inner, width, height, pixelX, pixelY, drag); } }; _proto.handleScrollX = function handleScrollX(left) { this.handleScroll(left, this.props.top, undefined, 0, { drag: true }); }; _proto.handleScrollY = function handleScrollY(top) { this.handleScroll(this.props.left, top, undefined, undefined, { drag: true }); }; _proto.handleTouchStart = function handleTouchStart(e) { this.setStartPoint(e.changedTouches[0]); }; _proto.handleTouchMove = function handleTouchMove(e) { var _this$props5 = this.props, scrollX = _this$props5.scrollX, scrollY = _this$props5.scrollY; e.preventDefault(); var position = e.changedTouches[0]; var moveX = position.clientX - this.touchStartX; var moveY = position.clientY - this.touchStartY; if (scrollX) this.pixelX = -moveX; if (scrollY) this.pixelY = -moveY; // need reset the start this.setStartPoint(position); this.boundleScroll(); } // handle inner scroll cased by input focus ; _proto.handleInnerScroll = function handleInnerScroll(e) { var target = e.target; var _this$props6 = this.props, _this$props6$scrollWi = _this$props6.scrollWidth, scrollWidth = _this$props6$scrollWi === void 0 ? Scroll.defaultProps.scrollWidth : _this$props6$scrollWi, _this$props6$scrollHe = _this$props6.scrollHeight, scrollHeight = _this$props6$scrollHe === void 0 ? Scroll.defaultProps.scrollHeight : _this$props6$scrollHe, left = _this$props6.left, top = _this$props6.top; var _this$getWheelRect2 = this.getWheelRect(), width = _this$getWheelRect2.width, height = _this$getWheelRect2.height; if (target.scrollLeft || target.scrollTop) { var sLeft = target.scrollLeft ? left + target.scrollLeft / (scrollWidth - width) : left; var sTop = target.scrollTop ? top + target.scrollTop / (scrollHeight - height) : top; sTop = Math.min(1, sTop); sTop = Math.max(0, sTop); sLeft = Math.min(1, sLeft); sLeft = Math.max(0, sLeft); this.handleScroll(sLeft, sTop, undefined, undefined, { drag: true }); target.scrollLeft = 0; target.scrollTop = 0; } }; _proto.render = function render() { var _this$props7 = this.props, _this$props7$scrollWi = _this$props7.scrollWidth, scrollWidth = _this$props7$scrollWi === void 0 ? Scroll.defaultProps.scrollWidth : _this$props7$scrollWi, _this$props7$scrollHe = _this$props7.scrollHeight, scrollHeight = _this$props7$scrollHe === void 0 ? Scroll.defaultProps.scrollHeight : _this$props7$scrollHe, children = _this$props7.children, left = _this$props7.left, top = _this$props7.top, scrollX = _this$props7.scrollX, scrollY = _this$props7.scrollY, style = _this$props7.style; var _this$getWheelRect3 = this.getWheelRect(), width = _this$getWheelRect3.width, height = _this$getWheelRect3.height; var rtl = (0, _config.isRTL)(); var className = (0, _classnames.default)((0, _styles.scrollClass)('_', scrollX && 'show-x', scrollY && 'show-y', rtl && 'rtl'), this.props.className); var yLength = scrollHeight < height ? scrollHeight : height; this.wheelY = scrollY && Math.ceil(scrollHeight) > Math.ceil(yLength); this.wheelX = scrollX && Math.ceil(scrollWidth) > Math.ceil(width); return _react.default.createElement(_react.default.Fragment, null, _react.default.createElement("div", { style: style, ref: this.bindWheel, className: className }, _react.default.createElement("iframe", { tabIndex: -1, title: "scroll", ref: this.bindIframe, className: (0, _styles.scrollClass)('iframe') }), _react.default.createElement("div", { className: (0, _styles.scrollClass)('iframe') }), _react.default.createElement("div", { ref: this.bindInner, className: (0, _styles.scrollClass)('inner') }, _react.default.createElement(_context.Provider, { value: { left: left * width, top: top * height, element: this.wheelElement } }, children)), scrollY && _react.default.createElement(_Bar.default, { direction: "y", length: yLength, forceHeight: scrollHeight < height ? scrollHeight : undefined, scrollLength: scrollHeight, offset: top, onScroll: this.handleScrollY }), scrollX && _react.default.createElement(_Bar.default, { direction: "x", length: width, scrollLength: scrollWidth, offset: left, onScroll: this.handleScrollX })), this.props.footer && _react.default.createElement("div", { ref: this.bindFooter, className: (0, _styles.scrollClass)('footer') }, this.props.footer)); }; return Scroll; }(_component.PureComponent); (0, _defineProperty2.default)(Scroll, "defaultProps", { scrollHeight: 0, scrollWidth: 0, innerScrollAttr: [] }); var _default = Scroll; exports.default = _default;