import { isPlainObject, supportsPassive } from 'uni-shared' import { hasLifecycleHook } from 'uni-helpers/index' import { NAVBAR_HEIGHT, TABBAR_HEIGHT } from 'uni-helpers/constants' import { disableScroll, createScrollListener } from 'uni-core/view/bridge/subscribe/scroll' const passiveOptions = supportsPassive ? { passive: false } : false function updateCssVar (vm) { if (uni.canIUse('css.var')) { const uniConfigTabbarHeight = parseFloat(__uniConfig.tabBar.height) const pageVm = vm.$parent.$parent const navigationBarType = pageVm.navigationBar.type const windowTopValue = navigationBarType === 'default' || navigationBarType === 'float' ? NAVBAR_HEIGHT : 0 const windowBottomValue = getApp().$children[0].showTabBar ? isNaN(uniConfigTabbarHeight) ? TABBAR_HEIGHT : uniConfigTabbarHeight : 0 const envMethod = uni.canIUse('css.env') ? 'env' : (uni.canIUse('css.constant') ? 'constant' : '') const windowTop = windowTopValue && envMethod ? `calc(${windowTopValue}px + ${envMethod}(safe-area-inset-top))` : `${windowTopValue}px` const windowBottom = windowBottomValue && envMethod ? `calc(${windowBottomValue}px + ${envMethod}(safe-area-inset-bottom))` : `${windowBottomValue}px` const style = document.documentElement.style style.setProperty('--window-top', `calc(var(--top-window-height) + ${windowTop})`) style.setProperty('--window-bottom', windowBottom) console.debug(`${vm.$page.route}[${vm.$page.id}]:--window-top=${windowTop}`) console.debug(`${vm.$page.route}[${vm.$page.id}]:--window-bottom=${windowBottom}`) } } export default function initSubscribe (subscribe) { let scrollListener = false let disableScrollListener = false subscribe('onPageLoad', vm => { // 用户 onLoad 之前 update updateCssVar(vm) }) subscribe('onPageShow', vm => { const pageVm = vm.$parent.$parent if (vm._isMounted) { // 非首次 show 才 update(首次 show 的时候在 onPageLoad 中触发了) updateCssVar(vm) } if (disableScrollListener) { document.removeEventListener('touchmove', disableScrollListener, passiveOptions) } if (pageVm.disableScroll) { disableScrollListener = disableScroll document.addEventListener('touchmove', disableScrollListener, passiveOptions) } const enablePageScroll = hasLifecycleHook(vm.$options, 'onPageScroll') const enablePageReachBottom = hasLifecycleHook(vm.$options, 'onReachBottom') const onReachBottomDistance = pageVm.onReachBottomDistance const enableTransparentTitleNView = (isPlainObject(pageVm.titleNView) && pageVm.titleNView.type === 'transparent') || (isPlainObject(pageVm.navigationBar) && pageVm.navigationBar.type === 'transparent') if (scrollListener) { document.removeEventListener('scroll', scrollListener) } if (enableTransparentTitleNView || enablePageScroll || enablePageReachBottom) { // 初始化 scroll 监听 scrollListener = createScrollListener(vm.$page.id, { enablePageScroll, enablePageReachBottom, onReachBottomDistance, enableTransparentTitleNView }) requestAnimationFrame(function () { // 避免监听太早,直接触发了 scroll document.addEventListener('scroll', scrollListener) }) } }) }