mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[improvement] sort out utils (#2672)
This commit is contained in:
parent
0eb06b10a8
commit
f0056297c6
@ -1,7 +1,13 @@
|
|||||||
import { use } from '../utils';
|
import { use } from '../utils';
|
||||||
import utils from '../utils/scroll';
|
|
||||||
import Loading from '../loading';
|
import Loading from '../loading';
|
||||||
import { on, off } from '../utils/event';
|
import { on, off } from '../utils/event';
|
||||||
|
import {
|
||||||
|
getScrollTop,
|
||||||
|
getElementTop,
|
||||||
|
getVisibleHeight,
|
||||||
|
getComputedStyle,
|
||||||
|
getScrollEventTarget
|
||||||
|
} from '../utils/scroll';
|
||||||
|
|
||||||
const [sfc, bem, t] = use('list');
|
const [sfc, bem, t] = use('list');
|
||||||
|
|
||||||
@ -28,7 +34,7 @@ export default sfc({
|
|||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.scroller = utils.getScrollEventTarget(this.$el);
|
this.scroller = getScrollEventTarget(this.$el);
|
||||||
this.handler(true);
|
this.handler(true);
|
||||||
|
|
||||||
if (this.immediateCheck) {
|
if (this.immediateCheck) {
|
||||||
@ -66,18 +72,14 @@ export default sfc({
|
|||||||
|
|
||||||
const el = this.$el;
|
const el = this.$el;
|
||||||
const { scroller } = this;
|
const { scroller } = this;
|
||||||
const scrollerHeight = utils.getVisibleHeight(scroller);
|
const scrollerHeight = getVisibleHeight(scroller);
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
if (
|
if (!scrollerHeight || getComputedStyle(el).display === 'none' || el.offsetParent === null) {
|
||||||
!scrollerHeight ||
|
|
||||||
utils.getComputedStyle(el).display === 'none' ||
|
|
||||||
el.offsetParent === null
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const scrollTop = utils.getScrollTop(scroller);
|
const scrollTop = getScrollTop(scroller);
|
||||||
const targetBottom = scrollTop + scrollerHeight;
|
const targetBottom = scrollTop + scrollerHeight;
|
||||||
|
|
||||||
let reachBottom = false;
|
let reachBottom = false;
|
||||||
@ -86,8 +88,7 @@ export default sfc({
|
|||||||
if (el === scroller) {
|
if (el === scroller) {
|
||||||
reachBottom = scroller.scrollHeight - targetBottom < this.offset;
|
reachBottom = scroller.scrollHeight - targetBottom < this.offset;
|
||||||
} else {
|
} else {
|
||||||
const elBottom =
|
const elBottom = getElementTop(el) - getElementTop(scroller) + getVisibleHeight(el);
|
||||||
utils.getElementTop(el) - utils.getElementTop(scroller) + utils.getVisibleHeight(el);
|
|
||||||
reachBottom = elBottom - scrollerHeight < this.offset;
|
reachBottom = elBottom - scrollerHeight < this.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +129,9 @@ export default sfc({
|
|||||||
<div class={bem('finished-text')}>{this.finishedText}</div>
|
<div class={bem('finished-text')}>{this.finishedText}</div>
|
||||||
)}
|
)}
|
||||||
{this.error && this.errorText && (
|
{this.error && this.errorText && (
|
||||||
<div onClick={this.clickErrorText} class={bem('error-text')}>{this.errorText}</div>
|
<div onClick={this.clickErrorText} class={bem('error-text')}>
|
||||||
|
{this.errorText}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import manager from './manager';
|
import manager from './manager';
|
||||||
import context from './context';
|
import context from './context';
|
||||||
import scrollUtils from '../../utils/scroll';
|
|
||||||
import { on, off } from '../../utils/event';
|
|
||||||
import Touch from '../touch';
|
import Touch from '../touch';
|
||||||
|
import { on, off } from '../../utils/event';
|
||||||
|
import { getScrollEventTarget } from '../../utils/scroll';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [Touch],
|
mixins: [Touch],
|
||||||
@ -159,7 +159,7 @@ export default {
|
|||||||
onTouchMove(e) {
|
onTouchMove(e) {
|
||||||
this.touchMove(e);
|
this.touchMove(e);
|
||||||
const direction = this.deltaY > 0 ? '10' : '01';
|
const direction = this.deltaY > 0 ? '10' : '01';
|
||||||
const el = scrollUtils.getScrollEventTarget(e.target, this.$el);
|
const el = getScrollEventTarget(e.target, this.$el);
|
||||||
const { scrollHeight, offsetHeight, scrollTop } = el;
|
const { scrollHeight, offsetHeight, scrollTop } = el;
|
||||||
let status = '11';
|
let status = '11';
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { use } from '../utils';
|
import { use } from '../utils';
|
||||||
import Loading from '../loading';
|
import Loading from '../loading';
|
||||||
import scrollUtils from '../utils/scroll';
|
|
||||||
import Touch from '../mixins/touch';
|
import Touch from '../mixins/touch';
|
||||||
|
import { getScrollTop, getScrollEventTarget } from '../utils/scroll';
|
||||||
|
|
||||||
const [sfc, bem, t] = use('pull-refresh');
|
const [sfc, bem, t] = use('pull-refresh');
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ export default sfc({
|
|||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.scrollEl = scrollUtils.getScrollEventTarget(this.$el);
|
this.scrollEl = getScrollEventTarget(this.$el);
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
@ -95,7 +95,7 @@ export default sfc({
|
|||||||
},
|
},
|
||||||
|
|
||||||
getCeiling() {
|
getCeiling() {
|
||||||
this.ceiling = scrollUtils.getScrollTop(this.scrollEl) === 0;
|
this.ceiling = getScrollTop(this.scrollEl) === 0;
|
||||||
return this.ceiling;
|
return this.ceiling;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { use, isDef } from '../utils';
|
import { use, isDef } from '../utils';
|
||||||
|
import Touch from '../mixins/touch';
|
||||||
import { raf } from '../utils/raf';
|
import { raf } from '../utils/raf';
|
||||||
import { on, off } from '../utils/event';
|
import { on, off } from '../utils/event';
|
||||||
import scrollUtils from '../utils/scroll';
|
import { setScrollTop, getScrollTop, getElementTop, getScrollEventTarget } from '../utils/scroll';
|
||||||
import Touch from '../mixins/touch';
|
|
||||||
|
|
||||||
const [sfc, bem] = use('tabs');
|
const [sfc, bem] = use('tabs');
|
||||||
const tabBem = use('tab')[1];
|
const tabBem = use('tab')[1];
|
||||||
@ -128,7 +128,7 @@ export default sfc({
|
|||||||
|
|
||||||
// scroll to correct position
|
// scroll to correct position
|
||||||
if (this.position === 'top' || this.position === 'bottom') {
|
if (this.position === 'top' || this.position === 'bottom') {
|
||||||
scrollUtils.setScrollTop(window, scrollUtils.getElementTop(this.$el));
|
setScrollTop(window, getElementTop(this.$el));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ export default sfc({
|
|||||||
// listen to scroll event
|
// listen to scroll event
|
||||||
if (events.sticky !== sticky) {
|
if (events.sticky !== sticky) {
|
||||||
events.sticky = sticky;
|
events.sticky = sticky;
|
||||||
this.scrollEl = this.scrollEl || scrollUtils.getScrollEventTarget(this.$el);
|
this.scrollEl = this.scrollEl || getScrollEventTarget(this.$el);
|
||||||
(sticky ? on : off)(this.scrollEl, 'scroll', this.onScroll, true);
|
(sticky ? on : off)(this.scrollEl, 'scroll', this.onScroll, true);
|
||||||
this.onScroll();
|
this.onScroll();
|
||||||
}
|
}
|
||||||
@ -215,8 +215,8 @@ export default sfc({
|
|||||||
|
|
||||||
// adjust tab position
|
// adjust tab position
|
||||||
onScroll() {
|
onScroll() {
|
||||||
const scrollTop = scrollUtils.getScrollTop(window) + this.offsetTop;
|
const scrollTop = getScrollTop(window) + this.offsetTop;
|
||||||
const elTopToPageTop = scrollUtils.getElementTop(this.$el);
|
const elTopToPageTop = getElementTop(this.$el);
|
||||||
const elBottomToPageTop =
|
const elBottomToPageTop =
|
||||||
elTopToPageTop + this.$el.offsetHeight - this.$refs.wrap.offsetHeight;
|
elTopToPageTop + this.$el.offsetHeight - this.$refs.wrap.offsetHeight;
|
||||||
if (scrollTop > elBottomToPageTop) {
|
if (scrollTop > elBottomToPageTop) {
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import use from './use';
|
|
||||||
import { useSlots } from './slots';
|
|
||||||
|
|
||||||
const isServer = Vue.prototype.$isServer;
|
export { use, useSlots } from './use';
|
||||||
|
|
||||||
function isDef(value) {
|
export const isServer = Vue.prototype.$isServer;
|
||||||
|
|
||||||
|
export function isDef(value) {
|
||||||
return value !== undefined && value !== null;
|
return value !== undefined && value !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isObj(x) {
|
export function isObj(x) {
|
||||||
const type = typeof x;
|
const type = typeof x;
|
||||||
return x !== null && (type === 'object' || type === 'function');
|
return x !== null && (type === 'object' || type === 'function');
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(object, path) {
|
export function get(object, path) {
|
||||||
const keys = path.split('.');
|
const keys = path.split('.');
|
||||||
let result = object;
|
let result = object;
|
||||||
|
|
||||||
@ -25,27 +25,15 @@ function get(object, path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const camelizeRE = /-(\w)/g;
|
const camelizeRE = /-(\w)/g;
|
||||||
function camelize(str) {
|
export function camelize(str) {
|
||||||
return str.replace(camelizeRE, (_, c) => c.toUpperCase());
|
return str.replace(camelizeRE, (_, c) => c.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAndroid() {
|
export function isAndroid() {
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
return isServer ? false : /android/.test(navigator.userAgent.toLowerCase());
|
return isServer ? false : /android/.test(navigator.userAgent.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
function range(num, min, max) {
|
export function range(num, min, max) {
|
||||||
return Math.min(Math.max(num, min), max);
|
return Math.min(Math.max(num, min), max);
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
|
||||||
use,
|
|
||||||
get,
|
|
||||||
range,
|
|
||||||
isObj,
|
|
||||||
isDef,
|
|
||||||
isServer,
|
|
||||||
useSlots,
|
|
||||||
camelize,
|
|
||||||
isAndroid
|
|
||||||
};
|
|
||||||
|
@ -1,36 +1,41 @@
|
|||||||
import { isServer } from '.';
|
import { isServer } from '.';
|
||||||
|
|
||||||
export default {
|
export const getComputedStyle = !isServer && document.defaultView.getComputedStyle.bind(document.defaultView);
|
||||||
|
|
||||||
// get nearest scroll element
|
// get nearest scroll element
|
||||||
getScrollEventTarget(element, rootParent = window) {
|
// http://w3help.org/zh-cn/causes/SD9013
|
||||||
|
// http://stackoverflow.com/questions/17016740/onscroll-function-is-not-working-for-chrome
|
||||||
|
export function getScrollEventTarget(element, rootParent = window) {
|
||||||
let node = element;
|
let node = element;
|
||||||
// bugfix, see http://w3help.org/zh-cn/causes/SD9013 and http://stackoverflow.com/questions/17016740/onscroll-function-is-not-working-for-chrome
|
while (
|
||||||
while (node && node.tagName !== 'HTML' && node.tagName !== 'BODY' && node.nodeType === 1 && node !== rootParent) {
|
node &&
|
||||||
const { overflowY } = this.getComputedStyle(node);
|
node.tagName !== 'HTML' &&
|
||||||
|
node.tagName !== 'BODY' &&
|
||||||
|
node.nodeType === 1 &&
|
||||||
|
node !== rootParent
|
||||||
|
) {
|
||||||
|
const { overflowY } = getComputedStyle(node);
|
||||||
if (overflowY === 'scroll' || overflowY === 'auto') {
|
if (overflowY === 'scroll' || overflowY === 'auto') {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
node = node.parentNode;
|
node = node.parentNode;
|
||||||
}
|
}
|
||||||
return rootParent;
|
return rootParent;
|
||||||
},
|
}
|
||||||
|
|
||||||
getScrollTop(element) {
|
export function getScrollTop(element) {
|
||||||
return 'scrollTop' in element ? element.scrollTop : element.pageYOffset;
|
return 'scrollTop' in element ? element.scrollTop : element.pageYOffset;
|
||||||
},
|
}
|
||||||
|
|
||||||
setScrollTop(element, value) {
|
export function setScrollTop(element, value) {
|
||||||
'scrollTop' in element ? element.scrollTop = value : element.scrollTo(element.scrollX, value);
|
'scrollTop' in element ? (element.scrollTop = value) : element.scrollTo(element.scrollX, value);
|
||||||
},
|
}
|
||||||
|
|
||||||
// get distance from element top to page top
|
// get distance from element top to page top
|
||||||
getElementTop(element) {
|
export function getElementTop(element) {
|
||||||
return (element === window ? 0 : element.getBoundingClientRect().top) + this.getScrollTop(window);
|
return (element === window ? 0 : element.getBoundingClientRect().top) + getScrollTop(window);
|
||||||
},
|
}
|
||||||
|
|
||||||
getVisibleHeight(element) {
|
export function getVisibleHeight(element) {
|
||||||
return element === window ? element.innerHeight : element.getBoundingClientRect().height;
|
return element === window ? element.innerHeight : element.getBoundingClientRect().height;
|
||||||
},
|
}
|
||||||
|
|
||||||
getComputedStyle: !isServer && document.defaultView.getComputedStyle.bind(document.defaultView)
|
|
||||||
};
|
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
export function useSlots({ $slots, $scopedSlots }) {
|
|
||||||
return (name, props) => {
|
|
||||||
if ($scopedSlots[name]) {
|
|
||||||
return $scopedSlots[name](props);
|
|
||||||
}
|
|
||||||
return $slots[name];
|
|
||||||
};
|
|
||||||
}
|
|
@ -2,7 +2,16 @@ import useBem from './bem';
|
|||||||
import useSfc from './sfc';
|
import useSfc from './sfc';
|
||||||
import useI18n from './i18n';
|
import useI18n from './i18n';
|
||||||
|
|
||||||
export default function (name) {
|
export function use(name) {
|
||||||
name = 'van-' + name;
|
name = 'van-' + name;
|
||||||
return [useSfc(name), useBem(name), useI18n(name)];
|
return [useSfc(name), useBem(name), useI18n(name)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useSlots({ $slots, $scopedSlots }) {
|
||||||
|
return (name, props) => {
|
||||||
|
if ($scopedSlots[name]) {
|
||||||
|
return $scopedSlots[name](props);
|
||||||
|
}
|
||||||
|
return $slots[name];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
/* eslint-disable no-underscore-dangle */
|
/* eslint-disable no-underscore-dangle */
|
||||||
import Utils from '../utils/scroll';
|
|
||||||
import { on, off } from '../utils/event';
|
import { on, off } from '../utils/event';
|
||||||
|
import {
|
||||||
|
getScrollTop,
|
||||||
|
getElementTop,
|
||||||
|
getVisibleHeight,
|
||||||
|
getScrollEventTarget
|
||||||
|
} from '../utils/scroll';
|
||||||
|
|
||||||
const CONTEXT = '@@Waterfall';
|
const CONTEXT = '@@Waterfall';
|
||||||
const OFFSET = 300;
|
const OFFSET = 300;
|
||||||
@ -12,8 +17,8 @@ function handleScrollEvent() {
|
|||||||
// 已被禁止的滚动处理
|
// 已被禁止的滚动处理
|
||||||
if (this.disabled) return;
|
if (this.disabled) return;
|
||||||
|
|
||||||
const targetScrollTop = Utils.getScrollTop(scrollEventTarget);
|
const targetScrollTop = getScrollTop(scrollEventTarget);
|
||||||
const targetVisibleHeight = Utils.getVisibleHeight(scrollEventTarget);
|
const targetVisibleHeight = getVisibleHeight(scrollEventTarget);
|
||||||
// 滚动元素可视区域下边沿到滚动元素元素最顶上 距离
|
// 滚动元素可视区域下边沿到滚动元素元素最顶上 距离
|
||||||
const targetBottom = targetScrollTop + targetVisibleHeight;
|
const targetBottom = targetScrollTop + targetVisibleHeight;
|
||||||
|
|
||||||
@ -25,7 +30,8 @@ function handleScrollEvent() {
|
|||||||
if (element === scrollEventTarget) {
|
if (element === scrollEventTarget) {
|
||||||
needLoadMoreToLower = scrollEventTarget.scrollHeight - targetBottom < this.offset;
|
needLoadMoreToLower = scrollEventTarget.scrollHeight - targetBottom < this.offset;
|
||||||
} else {
|
} else {
|
||||||
const elementBottom = Utils.getElementTop(element) - Utils.getElementTop(scrollEventTarget) + Utils.getVisibleHeight(element);
|
const elementBottom =
|
||||||
|
getElementTop(element) - getElementTop(scrollEventTarget) + getVisibleHeight(element);
|
||||||
needLoadMoreToLower = elementBottom - targetVisibleHeight < this.offset;
|
needLoadMoreToLower = elementBottom - targetVisibleHeight < this.offset;
|
||||||
}
|
}
|
||||||
if (needLoadMoreToLower) {
|
if (needLoadMoreToLower) {
|
||||||
@ -37,7 +43,7 @@ function handleScrollEvent() {
|
|||||||
if (element === scrollEventTarget) {
|
if (element === scrollEventTarget) {
|
||||||
needLoadMoreToUpper = targetScrollTop < this.offset;
|
needLoadMoreToUpper = targetScrollTop < this.offset;
|
||||||
} else {
|
} else {
|
||||||
const elementTop = Utils.getElementTop(element) - Utils.getElementTop(scrollEventTarget);
|
const elementTop = getElementTop(element) - getElementTop(scrollEventTarget);
|
||||||
needLoadMoreToUpper = elementTop + this.offset > 0;
|
needLoadMoreToUpper = elementTop + this.offset > 0;
|
||||||
}
|
}
|
||||||
if (needLoadMoreToUpper) {
|
if (needLoadMoreToUpper) {
|
||||||
@ -54,12 +60,12 @@ function doBindEvent() {
|
|||||||
this.el[CONTEXT].binded = true;
|
this.el[CONTEXT].binded = true;
|
||||||
|
|
||||||
this.scrollEventListener = handleScrollEvent.bind(this);
|
this.scrollEventListener = handleScrollEvent.bind(this);
|
||||||
this.scrollEventTarget = Utils.getScrollEventTarget(this.el);
|
this.scrollEventTarget = getScrollEventTarget(this.el);
|
||||||
|
|
||||||
const disabledExpr = this.el.getAttribute('waterfall-disabled');
|
const disabledExpr = this.el.getAttribute('waterfall-disabled');
|
||||||
let disabled = false;
|
let disabled = false;
|
||||||
if (disabledExpr) {
|
if (disabledExpr) {
|
||||||
this.vm.$watch(disabledExpr, (value) => {
|
this.vm.$watch(disabledExpr, value => {
|
||||||
this.disabled = value;
|
this.disabled = value;
|
||||||
this.scrollEventListener();
|
this.scrollEventListener();
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user