提交 6f01c20f 编写于 作者: fxy060608's avatar fxy060608

feat: add PageScrollTo

上级 f03c3e07
export const API_PAGE_SCROLL_TO = 'pageScrollTo'
export type API_TYPE_PAGE_SCROLL_TO = typeof uni.pageScrollTo
export const PageScrollToProtocol: ApiProtocol<API_TYPE_PAGE_SCROLL_TO> = {
scrollTop: {
type: Number,
required: true,
},
duration: {
type: Number,
},
scrollTop: Number,
selector: String,
duration: Number,
}
const DEFAULT_DURATION = 300
export const PageScrollToOptions: ApiOptions<API_TYPE_PAGE_SCROLL_TO> = {
......
import {isFunction, extend, isPlainObject, isString, invokeArrayFns as invokeArrayFns$1, hyphenate, isArray, hasOwn as hasOwn$1, isObject as isObject$1, capitalize, toRawType, makeMap as makeMap$1, isPromise} from "@vue/shared";
import {injectHook, createVNode, inject, provide, reactive, computed, nextTick, getCurrentInstance, onBeforeMount, onMounted, onBeforeActivate, onBeforeDeactivate, openBlock, createBlock, mergeProps, toDisplayString, ref, defineComponent, resolveComponent, toHandlers, renderSlot, watch, onActivated, onBeforeUnmount, withModifiers, withDirectives, vShow, vModelDynamic, createCommentVNode, createTextVNode, Fragment, renderList, vModelText, watchEffect, withCtx, KeepAlive, resolveDynamicComponent} from "vue";
import {once, passive, normalizeTarget, invokeArrayFns, NAVBAR_HEIGHT, parseQuery, decodedQuery, plusReady, debounce, PRIMARY_COLOR as PRIMARY_COLOR$1, removeLeadingSlash, getLen, updateElementStyle, addFont} from "@dcloudio/uni-shared";
import {once, passive, normalizeTarget, invokeArrayFns, NAVBAR_HEIGHT, parseQuery, decodedQuery, plusReady, debounce, PRIMARY_COLOR as PRIMARY_COLOR$1, removeLeadingSlash, getLen, updateElementStyle, addFont, scrollTo} from "@dcloudio/uni-shared";
import {useRoute, createRouter, createWebHistory, createWebHashHistory, isNavigationFailure, RouterView} from "vue-router";
function applyOptions(options, instance2, publicThis) {
Object.keys(options).forEach((name) => {
......@@ -4956,6 +4956,20 @@ const LoadFontFaceProtocol = {
},
desc: Object
};
const API_PAGE_SCROLL_TO = "pageScrollTo";
const PageScrollToProtocol = {
scrollTop: Number,
selector: String,
duration: Number
};
const DEFAULT_DURATION = 300;
const PageScrollToOptions = {
formatArgs: {
duration(value, params) {
params.duration = Math.max(0, parseInt(value + "") || DEFAULT_DURATION);
}
}
};
const FRONT_COLORS = ["#ffffff", "#000000"];
const API_SET_NAVIGATION_BAR_COLOR = "setNavigationBarColor";
const SetNavigationBarColorOptions = {
......@@ -12320,6 +12334,10 @@ const hideNavigationBarLoading = defineAsyncApi(API_HIDE_NAVIGATION_BAR_LOADING,
const setNavigationBarTitle = defineAsyncApi(API_SET_NAVIGATION_BAR_TITLE, (args, {resolve, reject}) => {
setNavigationBar(getCurrentPageMeta(), API_SET_NAVIGATION_BAR_TITLE, args, resolve, reject);
}, SetNavigationBarTitleProtocol);
const pageScrollTo = defineAsyncApi(API_PAGE_SCROLL_TO, ({scrollTop, selector, duration}, {resolve}) => {
scrollTo(selector || scrollTop || 0, duration);
resolve();
}, PageScrollToProtocol, PageScrollToOptions);
const showModal = defineAsyncApi(API_SHOW_MODAL, () => {
}, ShowModalProtocol, ShowModalOptions);
const showToast = defineAsyncApi(API_SHOW_TOAST, () => {
......@@ -12510,6 +12528,7 @@ var api = /* @__PURE__ */ Object.freeze({
showNavigationBarLoading,
hideNavigationBarLoading,
setNavigationBarTitle,
pageScrollTo,
showModal,
showToast,
hideToast,
......@@ -13555,4 +13574,4 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
]);
}
_sfc_main.render = _sfc_render;
export {_sfc_main$1 as AsyncErrorComponent, _sfc_main as AsyncLoadingComponent, _sfc_main$l as Audio, index$5 as Button, _sfc_main$k as Canvas, _sfc_main$j as Checkbox, _sfc_main$i as CheckboxGroup, _sfc_main$h as Editor, index$6 as Form, index$4 as Icon, index$3 as Image, _sfc_main$g as Input, _sfc_main$f as Label, LayoutComponent, _sfc_main$e as MovableView, _sfc_main$d as Navigator, index as PageComponent, _sfc_main$c as Progress, _sfc_main$b as Radio, _sfc_main$a as RadioGroup, ResizeSensor, _sfc_main$9 as RichText, _sfc_main$8 as ScrollView, _sfc_main$7 as Slider, _sfc_main$6 as SwiperItem, _sfc_main$5 as Switch, index$2 as Text, _sfc_main$4 as Textarea, UniServiceJSBridge$1 as UniServiceJSBridge, UniViewJSBridge$1 as UniViewJSBridge, _sfc_main$3 as Video, index$1 as View, addInterceptor, arrayBufferToBase64, base64ToArrayBuffer, canIUse, chooseFile, chooseImage, chooseVideo, clearStorage, clearStorageSync, closeSocket, connectSocket, createInnerAudioContext, createIntersectionObserver, createSelectorQuery, createVideoContext, cssBackdropFilter, cssConstant, cssEnv, cssVar, downloadFile, getApp$1 as getApp, getCurrentPages$1 as getCurrentPages, getFileInfo, getImageInfo, getLocation, getNetworkType, getStorage, getStorageInfo, getStorageInfoSync, getStorageSync, getSystemInfo, getSystemInfoSync, getVideoInfo, hideKeyboard, hideLoading, hideNavigationBarLoading, hideTabBar, hideTabBarRedDot, hideToast, loadFontFace, makePhoneCall, navigateBack, navigateTo, offAccelerometerChange, offCompassChange, offNetworkStatusChange, onAccelerometerChange, onCompassChange, onNetworkStatusChange, onSocketClose, onSocketError, onSocketMessage, onSocketOpen, onTabBarMidButtonTap, openDocument, index$7 as plugin, promiseInterceptor, reLaunch, redirectTo, removeInterceptor, removeStorage, removeStorageSync, removeTabBarBadge, request, sendSocketMessage, setNavigationBarColor, setNavigationBarTitle, setStorage, setStorageSync, setTabBarBadge, setTabBarItem, setTabBarStyle, setupApp, setupPage, showActionSheet, showLoading, showModal, showNavigationBarLoading, showTabBar, showTabBarRedDot, showToast, startAccelerometer, startCompass, stopAccelerometer, stopCompass, switchTab, uni$1 as uni, uploadFile, upx2px, useCustomEvent, usePageRoute, useSubscribe, vibrateLong, vibrateShort};
export {_sfc_main$1 as AsyncErrorComponent, _sfc_main as AsyncLoadingComponent, _sfc_main$l as Audio, index$5 as Button, _sfc_main$k as Canvas, _sfc_main$j as Checkbox, _sfc_main$i as CheckboxGroup, _sfc_main$h as Editor, index$6 as Form, index$4 as Icon, index$3 as Image, _sfc_main$g as Input, _sfc_main$f as Label, LayoutComponent, _sfc_main$e as MovableView, _sfc_main$d as Navigator, index as PageComponent, _sfc_main$c as Progress, _sfc_main$b as Radio, _sfc_main$a as RadioGroup, ResizeSensor, _sfc_main$9 as RichText, _sfc_main$8 as ScrollView, _sfc_main$7 as Slider, _sfc_main$6 as SwiperItem, _sfc_main$5 as Switch, index$2 as Text, _sfc_main$4 as Textarea, UniServiceJSBridge$1 as UniServiceJSBridge, UniViewJSBridge$1 as UniViewJSBridge, _sfc_main$3 as Video, index$1 as View, addInterceptor, arrayBufferToBase64, base64ToArrayBuffer, canIUse, chooseFile, chooseImage, chooseVideo, clearStorage, clearStorageSync, closeSocket, connectSocket, createInnerAudioContext, createIntersectionObserver, createSelectorQuery, createVideoContext, cssBackdropFilter, cssConstant, cssEnv, cssVar, downloadFile, getApp$1 as getApp, getCurrentPages$1 as getCurrentPages, getFileInfo, getImageInfo, getLocation, getNetworkType, getStorage, getStorageInfo, getStorageInfoSync, getStorageSync, getSystemInfo, getSystemInfoSync, getVideoInfo, hideKeyboard, hideLoading, hideNavigationBarLoading, hideTabBar, hideTabBarRedDot, hideToast, loadFontFace, makePhoneCall, navigateBack, navigateTo, offAccelerometerChange, offCompassChange, offNetworkStatusChange, onAccelerometerChange, onCompassChange, onNetworkStatusChange, onSocketClose, onSocketError, onSocketMessage, onSocketOpen, onTabBarMidButtonTap, openDocument, pageScrollTo, index$7 as plugin, promiseInterceptor, reLaunch, redirectTo, removeInterceptor, removeStorage, removeStorageSync, removeTabBarBadge, request, sendSocketMessage, setNavigationBarColor, setNavigationBarTitle, setStorage, setStorageSync, setTabBarBadge, setTabBarItem, setTabBarStyle, setupApp, setupPage, showActionSheet, showLoading, showModal, showNavigationBarLoading, showTabBar, showTabBarRedDot, showToast, startAccelerometer, startCompass, stopAccelerometer, stopCompass, switchTab, uni$1 as uni, uploadFile, upx2px, useCustomEvent, usePageRoute, useSubscribe, vibrateLong, vibrateShort};
......@@ -38,6 +38,7 @@ export * from './route/switchTab'
export * from './ui/loadFontFace'
export * from './ui/navigationBar'
export * from './ui/pageScrollTo'
export * from './ui/popup'
export * from './ui/tabBar'
......
import {
API_PAGE_SCROLL_TO,
API_TYPE_PAGE_SCROLL_TO,
defineAsyncApi,
PageScrollToOptions,
PageScrollToProtocol,
} from '@dcloudio/uni-api'
import { scrollTo } from '@dcloudio/uni-shared'
export const pageScrollTo = defineAsyncApi<API_TYPE_PAGE_SCROLL_TO>(
API_PAGE_SCROLL_TO,
({ scrollTop, selector, duration }, { resolve }) => {
scrollTo(selector! || scrollTop! || 0, duration!)
resolve()
},
PageScrollToProtocol,
PageScrollToOptions
)
......@@ -44,6 +44,40 @@ function addFont(family, source, desc) {
document.head.appendChild(style);
resolve();
});
}
function scrollTo(scrollTop, duration) {
if (shared.isString(scrollTop)) {
const el = document.querySelector(scrollTop);
if (el) {
scrollTop = el.getBoundingClientRect().top + window.pageYOffset;
}
}
if (scrollTop < 0) {
scrollTop = 0;
}
const documentElement = document.documentElement;
const { clientHeight, scrollHeight } = documentElement;
scrollTop = Math.min(scrollTop, scrollHeight - clientHeight);
if (duration === 0) {
// 部分浏览器(比如微信)中 scrollTop 的值需要通过 document.body 来控制
documentElement.scrollTop = document.body.scrollTop = scrollTop;
return;
}
if (window.scrollY === scrollTop) {
return;
}
const scrollTo = (duration) => {
if (duration <= 0) {
window.scrollTo(0, scrollTop);
return;
}
const distaince = scrollTop - window.scrollY;
requestAnimationFrame(function () {
window.scrollTo(0, window.scrollY + (distaince / duration) * 10);
scrollTo(duration - 10);
});
};
scrollTo(duration);
}
function plusReady(callback) {
......@@ -288,5 +322,6 @@ exports.parseQuery = parseQuery;
exports.passive = passive;
exports.plusReady = plusReady;
exports.removeLeadingSlash = removeLeadingSlash;
exports.scrollTo = scrollTo;
exports.stringifyQuery = stringifyQuery;
exports.updateElementStyle = updateElementStyle;
......@@ -72,6 +72,9 @@ export declare function removeLeadingSlash(str: string): string;
export declare const RESPONSIVE_MIN_WIDTH = 768;
declare function scrollTo_2(scrollTop: number | string, duration: number): void;
export { scrollTo_2 as scrollTo }
export declare function stringifyQuery(obj?: Record<string, any>, encodeStr?: typeof encodeURIComponent): string;
export declare const TABBAR_HEIGHT = 50;
......
import { isHTMLTag, isSVGTag, isPlainObject, isArray } from '@vue/shared';
import { isString, isHTMLTag, isSVGTag, isPlainObject, isArray } from '@vue/shared';
function passive(passive) {
return { passive };
......@@ -40,6 +40,40 @@ function addFont(family, source, desc) {
document.head.appendChild(style);
resolve();
});
}
function scrollTo(scrollTop, duration) {
if (isString(scrollTop)) {
const el = document.querySelector(scrollTop);
if (el) {
scrollTop = el.getBoundingClientRect().top + window.pageYOffset;
}
}
if (scrollTop < 0) {
scrollTop = 0;
}
const documentElement = document.documentElement;
const { clientHeight, scrollHeight } = documentElement;
scrollTop = Math.min(scrollTop, scrollHeight - clientHeight);
if (duration === 0) {
// 部分浏览器(比如微信)中 scrollTop 的值需要通过 document.body 来控制
documentElement.scrollTop = document.body.scrollTop = scrollTop;
return;
}
if (window.scrollY === scrollTop) {
return;
}
const scrollTo = (duration) => {
if (duration <= 0) {
window.scrollTo(0, scrollTop);
return;
}
const distaince = scrollTop - window.scrollY;
requestAnimationFrame(function () {
window.scrollTo(0, window.scrollY + (distaince / duration) * 10);
scrollTo(duration - 10);
});
};
scrollTo(duration);
}
function plusReady(callback) {
......@@ -258,4 +292,4 @@ const RESPONSIVE_MIN_WIDTH = 768;
const COMPONENT_NAME_PREFIX = 'VUni';
const PRIMARY_COLOR = '#007aff';
export { BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, NAVBAR_HEIGHT, PLUS_RE, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, TABBAR_HEIGHT, TAGS, addFont, debounce, decode, decodedQuery, getLen, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, normalizeDataset, normalizeTarget, once, parseQuery, passive, plusReady, removeLeadingSlash, stringifyQuery, updateElementStyle };
export { BUILT_IN_TAGS, COMPONENT_NAME_PREFIX, COMPONENT_PREFIX, COMPONENT_SELECTOR_PREFIX, NAVBAR_HEIGHT, PLUS_RE, PRIMARY_COLOR, RESPONSIVE_MIN_WIDTH, TABBAR_HEIGHT, TAGS, addFont, debounce, decode, decodedQuery, getLen, invokeArrayFns, isBuiltInComponent, isCustomElement, isNativeTag, normalizeDataset, normalizeTarget, once, parseQuery, passive, plusReady, removeLeadingSlash, scrollTo, stringifyQuery, updateElementStyle };
import { FontFaceDescriptors } from 'css-font-loading-module'
import { isString } from '@vue/shared'
export function passive(passive: boolean) {
return { passive }
......@@ -57,3 +58,38 @@ export function addFont(
resolve()
})
}
export function scrollTo(scrollTop: number | string, duration: number) {
if (isString(scrollTop)) {
const el = document.querySelector(scrollTop)
if (el) {
scrollTop = el.getBoundingClientRect().top + window.pageYOffset
}
}
if (scrollTop < 0) {
scrollTop = 0
}
const documentElement = document.documentElement
const { clientHeight, scrollHeight } = documentElement
scrollTop = Math.min(scrollTop as number, scrollHeight - clientHeight)
if (duration === 0) {
// 部分浏览器(比如微信)中 scrollTop 的值需要通过 document.body 来控制
documentElement.scrollTop = document.body.scrollTop = scrollTop
return
}
if (window.scrollY === scrollTop) {
return
}
const scrollTo = (duration: number) => {
if (duration <= 0) {
window.scrollTo(0, scrollTop as number)
return
}
const distaince = (scrollTop as number) - window.scrollY
requestAnimationFrame(function () {
window.scrollTo(0, window.scrollY + (distaince / duration) * 10)
scrollTo(duration - 10)
})
}
scrollTo(duration)
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册