[bugfix] compatible <body /> is the scene of the scrolling container (#3844)

This commit is contained in:
流采 2019-07-15 19:36:21 +08:00 committed by neverland
parent dbe56fd362
commit 511087bc74
6 changed files with 40 additions and 18 deletions

View File

@ -2,7 +2,7 @@ import Icon from '../icon';
import Cell from '../cell';
import { cellProps } from '../cell/shared';
import { preventDefault } from '../utils/dom/event';
import { getRootScrollTop } from '../utils/dom/scroll';
import { getRootScrollTop, setRootScrollTop } from '../utils/dom/scroll';
import { createNamespace, isObj, isDef, addUnit } from '../utils';
import { isIOS } from '../utils/validate/system';
@ -139,7 +139,7 @@ export default createComponent({
// https://developers.weixin.qq.com/community/develop/doc/00044ae90742f8c82fb78fcae56800
/* istanbul ignore next */
if (isIOS()) {
window.scrollTo(0, getRootScrollTop());
setRootScrollTop(getRootScrollTop());
}
},

View File

@ -7,6 +7,7 @@ import {
getScrollTop,
getElementTop,
getRootScrollTop,
setRootScrollTop,
getScrollEventTarget
} from '../utils/dom/scroll';
@ -77,9 +78,13 @@ export default createComponent({
methods: {
onScroll() {
const scrollTop = this.scroller === window
? getScrollTop(this.scroller)
: 0;
let scrollTop;
if (this.scroller === window || this.scroller === document.body) {
scrollTop = getScrollTop(this.scroller);
} else {
// see: https://github.com/youzan/vant/issues/3774
scrollTop = 0;
}
const rects = this.children.map(item => ({
height: item.height,
top: getElementTop(item.$el)
@ -154,7 +159,7 @@ export default createComponent({
match[0].scrollIntoView();
if (this.stickyOffsetTop) {
window.scrollTo(0, getRootScrollTop() - this.stickyOffsetTop);
setRootScrollTop(getRootScrollTop() - this.stickyOffsetTop);
}
this.$emit('select', match[0].index);

View File

@ -79,9 +79,14 @@ export default {
},
methods: {
onLoad(index) {
onLoad(index, isRefresh) {
const list = this.list[index];
list.loading = true;
setTimeout(() => {
if (isRefresh) {
list.items = [];
}
for (let i = 0; i < 10; i++) {
const text = list.items.length + 1;
list.items.push(text < 10 ? '0' + text : text);
@ -104,11 +109,10 @@ export default {
onRefresh(index) {
const list = this.list[index];
setTimeout(() => {
list.items = [];
list.error = false;
list.finished = false;
list.refreshing = false;
window.scrollTo(0, 10);
this.onLoad(index, true);
}, 1000);
}
}

View File

@ -1,5 +1,5 @@
import { createNamespace, isDef, addUnit } from '../utils';
import { getRootScrollTop } from '../utils/dom/scroll';
import { getRootScrollTop, setRootScrollTop } from '../utils/dom/scroll';
import { isIOS } from '../utils/validate/system';
const [createComponent, bem] = createNamespace('stepper');
@ -160,7 +160,7 @@ export default createComponent({
// https://developers.weixin.qq.com/community/develop/doc/00044ae90742f8c82fb78fcae56800
/* istanbul ignore next */
if (isIOS()) {
window.scrollTo(0, getRootScrollTop());
setRootScrollTop(getRootScrollTop());
}
},

View File

@ -4,7 +4,7 @@ import { on, off } from '../utils/dom/event';
import { ParentMixin } from '../mixins/relation';
import { BindEventMixin } from '../mixins/bind-event';
import {
setScrollTop,
setRootScrollTop,
getScrollTop,
getElementTop,
getScrollEventTarget
@ -145,7 +145,7 @@ export default createComponent({
// scroll to correct position
if (this.position === 'top' || this.position === 'bottom') {
setScrollTop(window, getElementTop(this.$el) - this.offsetTop);
setRootScrollTop(getElementTop(this.$el) - this.offsetTop);
}
},
@ -184,7 +184,7 @@ export default createComponent({
// adjust tab position
onScroll() {
const scrollTop = getScrollTop(window) + this.offsetTop;
const scrollTop = getScrollTop(this.scrollEl) + this.offsetTop;
const elTopToPageTop = getElementTop(this.$el);
const elBottomToPageTop =
elTopToPageTop + this.$el.offsetHeight - this.$refs.wrap.offsetHeight;

View File

@ -3,18 +3,26 @@ type ScrollElement = HTMLElement | Window;
// get nearest scroll element
// http://w3help.org/zh-cn/causes/SD9013
// http://stackoverflow.com/questions/17016740/onscroll-function-is-not-working-for-chrome
const overflowScrollReg = /scroll|auto/i;
export function getScrollEventTarget(element: HTMLElement, rootParent: ScrollElement = window) {
let node = element;
while (
node &&
node.tagName !== 'HTML' &&
node.tagName !== 'BODY' &&
node.nodeType === 1 &&
node !== rootParent
) {
const { overflowY } = window.getComputedStyle(node);
if (overflowY === 'scroll' || overflowY === 'auto') {
return node;
if (overflowScrollReg.test(<string>overflowY)) {
if (node.tagName !== 'BODY') {
return node;
}
// see: https://github.com/youzan/vant/issues/3823
const { overflowY: htmlOverflowY } = window.getComputedStyle(<Element>node.parentNode);
if (overflowScrollReg.test(<string>htmlOverflowY)) {
return node;
}
}
node = <HTMLElement>node.parentNode;
}
@ -33,11 +41,16 @@ export function getRootScrollTop(): number {
return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
}
export function setRootScrollTop(value: number) {
setScrollTop(window, value);
setScrollTop(document.body, value);
}
// get distance from element top to page top
export function getElementTop(element: ScrollElement) {
return (
(element === window ? 0 : (<HTMLElement>element).getBoundingClientRect().top) +
getScrollTop(window)
getRootScrollTop()
);
}