63 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
			
		
		
	
	
			63 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
| /* eslint-disable no-param-reassign */
 | |
| 
 | |
| let cached: number;
 | |
| 
 | |
| export default function getScrollBarSize(fresh?: boolean) {
 | |
|   if (typeof document === 'undefined') {
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   if (fresh || cached === undefined) {
 | |
|     const inner = document.createElement('div');
 | |
|     inner.style.width = '100%';
 | |
|     inner.style.height = '200px';
 | |
| 
 | |
|     const outer = document.createElement('div');
 | |
|     const outerStyle = outer.style;
 | |
| 
 | |
|     outerStyle.position = 'absolute';
 | |
|     outerStyle.top = '0';
 | |
|     outerStyle.left = '0';
 | |
|     outerStyle.pointerEvents = 'none';
 | |
|     outerStyle.visibility = 'hidden';
 | |
|     outerStyle.width = '200px';
 | |
|     outerStyle.height = '150px';
 | |
|     outerStyle.overflow = 'hidden';
 | |
| 
 | |
|     outer.appendChild(inner);
 | |
| 
 | |
|     document.body.appendChild(outer);
 | |
| 
 | |
|     const widthContained = inner.offsetWidth;
 | |
|     outer.style.overflow = 'scroll';
 | |
|     let widthScroll = inner.offsetWidth;
 | |
| 
 | |
|     if (widthContained === widthScroll) {
 | |
|       widthScroll = outer.clientWidth;
 | |
|     }
 | |
| 
 | |
|     document.body.removeChild(outer);
 | |
| 
 | |
|     cached = widthContained - widthScroll;
 | |
|   }
 | |
|   return cached;
 | |
| }
 | |
| 
 | |
| function ensureSize(str: string) {
 | |
|   const match = str.match(/^(.*)px$/);
 | |
|   const value = Number(match?.[1]);
 | |
|   return Number.isNaN(value) ? getScrollBarSize() : value;
 | |
| }
 | |
| 
 | |
| export function getTargetScrollBarSize(target: HTMLElement) {
 | |
|   if (typeof document === 'undefined' || !target || !(target instanceof Element)) {
 | |
|     return { width: 0, height: 0 };
 | |
|   }
 | |
| 
 | |
|   const { width, height } = getComputedStyle(target, '::-webkit-scrollbar');
 | |
|   return {
 | |
|     width: ensureSize(width),
 | |
|     height: ensureSize(height),
 | |
|   };
 | |
| }
 |