UNPKG

vuescroll

Version:

A beautiful scrollbar based on Vue.js for PC and mobile.

217 lines (193 loc) 5.13 kB
import Vue from 'vue'; export function deepCopy(source, target) { target = (typeof target === 'object' && target) || {}; for (var key in source) { target[key] = typeof source[key] === 'object' ? deepCopy(source[key], (target[key] = {})) : source[key]; } return target; } export function deepMerge(from, to) { to = to || {}; for (var key in from) { if (typeof from[key] === 'object') { if (typeof to[key] === 'undefined') { to[key] = {}; deepCopy(from[key], to[key]); } else { deepMerge(from[key], to[key]); } } else { if (typeof to[key] === 'undefined') to[key] = from[key]; } } return to; } export function defineReactive(target, key, source, souceKey) { let getter = null; /* istanbul ignore if */ if (!source[key] && typeof source !== 'function') { return; } souceKey = souceKey || key; if (typeof source === 'function') { getter = source; } Object.defineProperty(target, key, { get: getter || function() { return source[souceKey]; }, configurable: true }); } let scrollBarWidth; export function getGutter() { /* istanbul ignore next */ if (Vue.prototype.$isServer) return 0; if (scrollBarWidth !== undefined) return scrollBarWidth; const outer = document.createElement('div'); outer.style.visibility = 'hidden'; outer.style.width = '100px'; outer.style.position = 'absolute'; outer.style.top = '-9999px'; document.body.appendChild(outer); const widthNoScroll = outer.offsetWidth; outer.style.overflow = 'scroll'; const inner = document.createElement('div'); inner.style.width = '100%'; outer.appendChild(inner); const widthWithScroll = inner.offsetWidth; outer.parentNode.removeChild(outer); scrollBarWidth = widthNoScroll - widthWithScroll; return scrollBarWidth; } export function eventCenter( dom, eventName, hander, capture = false, type = 'on' ) { type == 'on' ? dom.addEventListener(eventName, hander, capture) : dom.removeEventListener(eventName, hander, capture); } export const error = msg => { console.error(`[vuescroll] ${msg}`); }; export const warn = msg => { console.warn(`[vuescroll] ${msg}`); }; export function isChildInParent(child, parent) { let flag = false; if (!child || !parent) { return flag; } while ( child.parentNode !== parent && child.parentNode.nodeType !== 9 && !child.parentNode._isVuescroll ) { child = child.parentNode; } if (child.parentNode == parent) { flag = true; } return flag; } const pxValueReg = /(.*?)px/; export function extractNumberFromPx(value) { const _return = pxValueReg.exec(value); return _return && _return[1]; } export function isSupportTouch() { return 'ontouchstart' in window; } export function getPrefix(global) { var docStyle = document.documentElement.style; var engine; /* istanbul ignore if */ if ( global.opera && Object.prototype.toString.call(opera) === '[object Opera]' ) { engine = 'presto'; } /* istanbul ignore next */ else if ('MozAppearance' in docStyle) { engine = 'gecko'; } else if ('WebkitAppearance' in docStyle) { engine = 'webkit'; } /* istanbul ignore next */ else if ( typeof navigator.cpuClass === 'string' ) { engine = 'trident'; } var vendorPrefix = { trident: 'ms', gecko: 'moz', webkit: 'webkit', presto: 'O' }[engine]; return vendorPrefix; } export function isSupportGivenStyle(property, value) { const compatibleValue = `-${getPrefix(window)}-${value}`; const testElm = document.createElement('div'); testElm.style[property] = compatibleValue; if (testElm.style[property] == compatibleValue) { return compatibleValue; } /* istanbul ignore next */ return false; } export function isIE() /* istanbul ignore next */ { var agent = navigator.userAgent.toLowerCase(); return ( agent.indexOf('msie') !== -1 || agent.indexOf('trident') !== -1 || agent.indexOf(' edge/') !== -1 ); } export function insertChildrenIntoSlot(h, parentVnode, childVNode, data) { parentVnode = parentVnode[0] ? parentVnode[0] : parentVnode; const tag = (parentVnode.componentOptions && parentVnode.componentOptions.tag) || parentVnode.tag; // if (!Array.isArray(childVNode)) { // childVNode = [childVNode]; // } // // Remove null node // for (let index = 0; index < childVNode.length; index++) { // const element = childVNode[index]; // if (!element) { // childVNode.splice(index, 1); // index--; // } // } const _data = parentVnode.componentOptions || parentVnode.data || {}; // If component, use `nativeOn` intead. if (parentVnode.componentOptions) { data.nativeOn = data.on; _data.props = _data.propsData; delete data.on; delete data.propsData; } return h( tag, { ...data, ..._data }, childVNode ); } export function getRealParent(ctx) { let parent = ctx.$parent; if (!parent._isVuescrollRoot && parent) { parent = parent.$parent; } return parent; }