element-plus/packages/utils/dom/scroll.ts

63 lines
1.6 KiB
TypeScript
Raw Normal View History

import { isClient } from '@vueuse/core'
import { getStyle } from './style'
export const isScroll = (el: HTMLElement, isVertical?: boolean): boolean => {
if (!isClient) return false
const key = (
{
undefined: 'overflow',
true: 'overflow-y',
false: 'overflow-x',
} as const
)[String(isVertical)]!
const overflow = getStyle(el, key)
return ['scroll', 'auto', 'overlay'].some((s) => overflow.includes(s))
}
export const getScrollContainer = (
el: HTMLElement,
isVertical?: boolean
): Window | HTMLElement | undefined => {
if (!isClient) return
let parent: HTMLElement = el
while (parent) {
if ([window, document, document.documentElement].includes(parent))
return window
if (isScroll(parent, isVertical)) return parent
parent = parent.parentNode as HTMLElement
}
return parent
}
let scrollBarWidth: number
export const getScrollBarWidth = (): number => {
if (!isClient) return 0
if (scrollBarWidth !== undefined) return scrollBarWidth
const outer = document.createElement('div')
outer.className = 'el-scrollbar__wrap'
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
}