UNPKG

vue-scrollbar-live

Version:
627 lines (544 loc) 17.9 kB
/** * Bundle of vue-scrollbar-live * Generated: 2020-05-19 * Version: 5.7.1 * License: MIT * Author: 2631541504@qq.com */ import { DragMove, Utils } from '@livelybone/mouse-events'; import { getNativeScrollbarWidth } from '@livelybone/scroll-get'; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var scrollbarType = { x: { posPropName: 'left', parentScrollPos: 'scrollLeft', deltaName: 'deltaX', sizeName: 'width' }, y: { posPropName: 'top', parentScrollPos: 'scrollTop', deltaName: 'deltaY', sizeName: 'height' } }; var showStyle = { opacity: 1, pointerEvents: 'initial' }; var script = { name: 'Bar', props: { type: String, parentScroll: Number, marginToWrap: { type: Number, default: 5 }, clientSize: Number, scrollSize: Number }, data: function data() { return { sPosition: 0, showBar: false, unbind: null, startPosition: 0 }; }, computed: { $_show: function $_show() { return this.scrollSize > this.clientSize; }, $_scrollbarType: function $_scrollbarType() { return scrollbarType[this.type]; }, size: function size() { return this.clientSize / this.scrollSize * this.clientSize - this.marginToWrap * 2; }, positionRange: function positionRange() { return { min: this.marginToWrap, max: this.clientSize - this.marginToWrap - this.size }; }, $_barStyle: function $_barStyle() { var _objectSpread2$1; return _objectSpread2({}, this.showBar ? showStyle : {}, (_objectSpread2$1 = {}, _defineProperty(_objectSpread2$1, this.$_scrollbarType.posPropName, "".concat(this.sPosition, "px !important")), _defineProperty(_objectSpread2$1, this.$_scrollbarType.sizeName, "".concat(this.size, "px !important")), _defineProperty(_objectSpread2$1, "userSelect", 'none'), _objectSpread2$1)); } }, watch: { $_show: { handler: function handler(val) { var _this = this; this.$nextTick(function () { if (_this.unbind) _this.unbind(); if (val && typeof window !== 'undefined' && _this.$el) { _this.unbind = DragMove.bind(_this.$el, _this.drag); } }); }, immediate: true }, parentScroll: { handler: function handler(val) { this.sPosition = (this.positionRange.max - this.positionRange.min) / (this.scrollSize - this.clientSize) * val + this.positionRange.min; }, immediate: true } }, methods: { drag: function drag(ev) { ev.originalEvent.preventDefault(); if (ev.type === 'dragMoveStart') this.startPosition = this.sPosition; var position = Math.min(this.positionRange.max, Math.max(this.positionRange.min, this.startPosition + ev[this.$_scrollbarType.deltaName])); this.$emit('scrollTo', _defineProperty({}, this.$_scrollbarType.parentScrollPos, (position - this.marginToWrap) / (this.positionRange.max - this.marginToWrap) * (this.scrollSize - this.clientSize))); this.showBar = ev.type !== 'dragMoveEnd'; } }, beforeDestroy: function beforeDestroy() { if (this.unbind) this.unbind(); } }; function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */ , shadowMode, createInjector, createInjectorSSR, createInjectorShadow) { if (typeof shadowMode !== 'boolean') { createInjectorSSR = createInjector; createInjector = shadowMode; shadowMode = false; } // Vue.extend constructor export interop. var options = typeof script === 'function' ? script.options : script; // render functions if (template && template.render) { options.render = template.render; options.staticRenderFns = template.staticRenderFns; options._compiled = true; // functional template if (isFunctionalTemplate) { options.functional = true; } } // scopedId if (scopeId) { options._scopeId = scopeId; } var hook; if (moduleIdentifier) { // server build hook = function hook(context) { // 2.3 injection context = context || // cached call this.$vnode && this.$vnode.ssrContext || // stateful this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext; // functional // 2.2 with runInNewContext: true if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { context = __VUE_SSR_CONTEXT__; } // inject component styles if (style) { style.call(this, createInjectorSSR(context)); } // register component module identifier for async chunk inference if (context && context._registeredComponents) { context._registeredComponents.add(moduleIdentifier); } }; // used by ssr in case component is cached and beforeCreate // never gets called options._ssrRegister = hook; } else if (style) { hook = shadowMode ? function () { style.call(this, createInjectorShadow(this.$root.$options.shadowRoot)); } : function (context) { style.call(this, createInjector(context)); }; } if (hook) { if (options.functional) { // register for functional component in vue file var originalRender = options.render; options.render = function renderWithStyleInjection(h, context) { hook.call(context); return originalRender(h, context); }; } else { // inject component registration as beforeCreate hook var existing = options.beforeCreate; options.beforeCreate = existing ? [].concat(existing, hook) : [hook]; } } return script; } var normalizeComponent_1 = normalizeComponent; /* script */ var __vue_script__ = script; /* template */ var __vue_render__ = function __vue_render__() { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c('div', { directives: [{ name: "show", rawName: "v-show", value: _vm.$_show, expression: "$_show" }], staticClass: "scrollbar", class: 'scrollbar-' + _vm.type, style: _vm.$_barStyle, attrs: { "draggable": false } }); }; var __vue_staticRenderFns__ = []; /* style */ var __vue_inject_styles__ = undefined; /* scoped */ var __vue_scope_id__ = undefined; /* module identifier */ var __vue_module_identifier__ = undefined; /* functional template */ var __vue_is_functional_template__ = false; /* style inject */ /* style inject SSR */ var Bar = normalizeComponent_1({ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ }, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, undefined, undefined); // eslint-disable-next-line import/no-extraneous-dependencies function listenDomChange(comp, cb) { if ('MutationObserver' in window) { var observer = new MutationObserver(function (records) { var childrenChangeExceptScrollbar = records.some(function (r) { var target = r.target; if (comp.$el.contains(target)) { if (!(target instanceof Element)) return true; var className = target.className; return !/^scrollbar\s/.test(className); } return target.contains(comp.$el); }); if (childrenChangeExceptScrollbar) cb(); }); observer.observe(document.body, { attributes: true, childList: true, subtree: true }); return function () { observer.disconnect(); }; } // If MutationObserver is not available, use updated lifecycle of Vue to call the cb // This will bring up a problem that the width/height data cannot be calculated at the right time in a async render scene comp.$on('hook:updated', cb); return function () {}; } function insertStyle() { var id = 'vue-scrollbar-live-module-style'; var styleExist = document.getElementById(id); if (!styleExist) { var style = document.createElement('style'); style.id = id; style.innerText = '.scrollbar-wrap .scrollbar-content::-webkit-scrollbar{width:0;height:0;}' + '.scrollbar-wrap .scrollbar-content{-ms-overflow-style:none;scrollbar-width:none;}' + '.scrollbar-wrap .scrollbar{position:absolute;border-radius:.25em;background:#eee;box-shadow:0 0 2px rgba(0,0,0,0.1);opacity:0;pointer-events:none}' + '.scrollbar-wrap .scrollbar-y{right:0.25em;width:.5em}' + '.scrollbar-wrap .scrollbar-x{bottom:0.25em;height:.5em}' + '.scrollbar-wrap:hover .scrollbar{opacity:1;pointer-events:initial}'; document.head.appendChild(style); } } // var script$1 = { name: 'Scrollbar', components: { Bar: Bar }, props: { isMobile: Boolean, maxHeight: [Number, String], scrollTo: [Number, Object], marginToWrap: { default: 5, type: Number } }, data: function data() { return { width: { parent: 0, content: 0, contentInner: 0 }, height: { parent: 0, content: 0, contentInner: 0 }, scrollPos: { scrollLeft: 0, scrollTop: 0 }, isTop: true, isBottom: true, isLeft: true, isRight: true, nativeScrollbarWidth: { x: 0, y: 0 } }; }, computed: { scrollbars: function scrollbars() { return { x: { scrollPropName: 'scrollLeft', size: this.width }, y: { scrollPropName: 'scrollTop', size: this.height } }; }, $_maxHeight: function $_maxHeight() { var _this = this; if (typeof this.maxHeight === 'number') return "".concat(this.maxHeight, "px"); if (/%/.test(this.maxHeight)) { return this.maxHeight.replace(/(\d+)%/g, function (m, percent) { return "".concat(_this.height.parent * percent / 100, "px"); }); } return this.maxHeight; }, $_wrapStyle: function $_wrapStyle() { return { position: 'relative', height: this.isMobile ? 'auto !important' : "".concat(this.height.content, "px !important"), maxHeight: "".concat(this.$_maxHeight, " !important"), padding: '0 !important', overflow: 'hidden !important' }; }, $_contentStyle: function $_contentStyle() { if (this.isMobile) { return { maxHeight: this.$_maxHeight, overflow: 'scroll' }; } var _this$nativeScrollbar = this.nativeScrollbarWidth, x = _this$nativeScrollbar.x, y = _this$nativeScrollbar.y; return { width: "calc(100% + ".concat(y, "px) !important"), maxHeight: "calc(".concat(this.$_maxHeight.replace(/(^calc\()|(\)$)/g, ''), " + ").concat(x, "px) !important"), overflow: 'scroll' }; }, maxScroll: function maxScroll() { return { scrollLeft: this.width.contentInner - this.width.content, scrollTop: this.height.contentInner - this.height.content }; } }, watch: { scrollTo: { handler: function handler(val) { this.$scrollTo(val); }, immediate: true }, isBottom: function isBottom(val) { if (val) this.$emit('reachBottom'); }, isTop: function isTop(val) { if (val) this.$emit('reachTop'); }, isLeft: function isLeft(val) { if (val) this.$emit('reachLeft'); }, isRight: function isRight(val) { if (val) this.$emit('reachRight'); } }, methods: { updateScrollbarWidth: function updateScrollbarWidth() { this.nativeScrollbarWidth = getNativeScrollbarWidth(this.$refs.content); }, updateHeight: function updateHeight() { if (!this.$refs.content || typeof window === 'undefined') return; var _this$$refs$content = this.$refs.content, scrollHeight = _this$$refs$content.scrollHeight, clientHeight = _this$$refs$content.clientHeight, scrollWidth = _this$$refs$content.scrollWidth, clientWidth = _this$$refs$content.clientWidth; this.height.content = clientHeight; this.height.contentInner = scrollHeight; this.height.parent = this.$refs.wrap.parentElement.clientHeight; this.width.content = clientWidth; this.width.contentInner = scrollWidth; this.width.parent = this.$refs.wrap.parentElement.clientWidth; }, getHeight: function getHeight() { this.updateHeight(); }, $scrollTo: function $scrollTo(val) { var _this2 = this; this.$nextTick(function () { if (val !== undefined && val !== null) { var pos = { scrollLeft: 0, scrollTop: 0 }; if (val.x || val.y) { pos.scrollLeft = +val.x * _this2.maxScroll.scrollLeft; pos.scrollTop = +val.y * _this2.maxScroll.scrollTop; } else { pos.scrollLeft = +val * _this2.maxScroll.scrollLeft; pos.scrollTop = +val * _this2.maxScroll.scrollTop; } _this2.setScroll(pos, 'drag'); } }); }, scroll: function scroll(e) { var _this$$refs$content2 = this.$refs.content, scrollTop = _this$$refs$content2.scrollTop, scrollLeft = _this$$refs$content2.scrollLeft; this.setScroll({ scrollTop: scrollTop, scrollLeft: scrollLeft }); this.$emit('scroll', e); }, setScroll: function setScroll(_ref) { var scrollTop = _ref.scrollTop, scrollLeft = _ref.scrollLeft; var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'scroll'; var needScroll = type !== 'scroll'; if (scrollTop !== undefined) { this.setPos(scrollTop, 'scrollTop', needScroll); } if (scrollLeft !== undefined) { this.setPos(scrollLeft, 'scrollLeft', needScroll); } this.judgeOnBoundary(); }, setPos: function setPos(val, type, needScroll) { this.scrollPos[type] = val; if (needScroll) this.$refs.content[type] = val; }, judgeOnBoundary: function judgeOnBoundary() { this.isTop = this.scrollPos.scrollTop === 0; this.isBottom = this.scrollPos.scrollTop === this.maxScroll.scrollTop; this.isLeft = this.scrollPos.scrollLeft === 0; this.isRight = this.scrollPos.scrollLeft === this.maxScroll.scrollLeft; } }, created: function created() { var _this3 = this; var inPcBrowser = !this.isMobile && typeof window !== 'undefined'; if (inPcBrowser) insertStyle(); this.$once('hook:mounted', function () { if (inPcBrowser) { _this3.updateScrollbarWidth(); _this3.$once('hook:beforeDestroy', Utils.$addListener(_this3.$refs.content, 'scroll', _this3.scroll)); } _this3.updateHeight(); _this3.$on('hook:beforeDestroy', listenDomChange(_this3, function () { _this3.$emit('domChange'); _this3.updateScrollbarWidth(); _this3.updateHeight(); })); }); } }; /* script */ var __vue_script__$1 = script$1; /* template */ var __vue_render__$1 = function __vue_render__() { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c('div', { ref: "wrap", staticClass: "scrollbar-wrap", style: _vm.$_wrapStyle, on: { "click": function click($event) { return _vm.$emit('wrapClick', $event); } } }, [_c('div', { ref: "content", staticClass: "scrollbar-content", style: _vm.$_contentStyle }, [_vm._t("default")], 2), _vm._v(" "), !_vm.isMobile && _vm.width.content && _vm.height.content ? _vm._l(_vm.scrollbars, function (barInfo, type) { return _c('Bar', { key: type, attrs: { "type": type, "marginToWrap": _vm.marginToWrap, "parentScroll": _vm.scrollPos[barInfo.scrollPropName], "clientSize": barInfo.size.content, "scrollSize": barInfo.size.contentInner }, on: { "scrollTo": function scrollTo($event) { return _vm.setScroll($event, 'drag'); } } }); }) : _vm._e()], 2); }; var __vue_staticRenderFns__$1 = []; /* style */ var __vue_inject_styles__$1 = undefined; /* scoped */ var __vue_scope_id__$1 = undefined; /* module identifier */ var __vue_module_identifier__$1 = undefined; /* functional template */ var __vue_is_functional_template__$1 = false; /* style inject */ /* style inject SSR */ var VueScrollbar = normalizeComponent_1({ render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 }, __vue_inject_styles__$1, __vue_script__$1, __vue_scope_id__$1, __vue_is_functional_template__$1, __vue_module_identifier__$1, undefined, undefined); export default VueScrollbar;