@cherrywind/flexible 0.0.5-alpha.1 → 0.0.5-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=(e={})=>{const{breakpoints:s=[768],layouts:i,basicLayout:l,scope:o,immediate:p=!1,orientationchange:m=!0,ratio:h,recalibrate:S=!0,resizeOption:E,onInitialized:u}=e,b=s,t=i,x=l??(t==null?void 0:t.at(-1)),L="--local-scope-rem",T=D()>0;let n=h;n&&(t==null?void 0:t.length)!==n.length&&t&&(n=[...n,...Array.from({length:t.length-n.length},()=>1)]);const W=c=>!t||!x?1:t.length-1===b.length?x/t[c]:1,f=()=>{const c=()=>{const y=window.innerWidth;let a=document.documentElement.clientWidth/100,A=!1,g=0;if(t){for(let r=0;r<b.length;r++)if(y<=b[r]){a=a*W(r)*((n==null?void 0:n[r])??1),A=!0,g=r;break}A||(a=a*W(t.length-1)*((n==null?void 0:n[t.length-1])??1),g=t.length-1)}if(o)if(Array.isArray(o))o.forEach(r=>{const{element:v=document.documentElement,cssVarName:k=L,ratio:w}=r,C=(w==null?void 0:w[g])??(n==null?void 0:n[g])??1;v.style.setProperty(k,a*C+"px")});else{const{element:r=document.documentElement,cssVarName:v=L}=o;r.style.setProperty(v,a+"px")}else document.documentElement.style.fontSize=a+"px"};c(),S&&T&&requestAnimationFrame(c)};let d=f;if(E){const{type:c,delay:y=150}=E;c==="debounce"?d=q(f,y):c==="throttle"&&(d=B(f,y))}return p?(f(),requestAnimationFrame(()=>{u==null||u()})):window.addEventListener("load",()=>{f(),requestAnimationFrame(()=>{u==null||u()})}),window.addEventListener("resize",d),m&&screen.orientation.addEventListener("change",d),()=>{window.removeEventListener("resize",d),m&&screen.orientation.removeEventListener("change",d)}};function q(e,s){let i=null;return function(...l){const o=this;i&&clearTimeout(i),i=setTimeout(()=>{i=null,e.apply(o,l)},s)}}function B(e,s){let i=0,l=null,o=null;return function(...p){const m=Date.now(),h=s-(m-i);o=p,h<=0?(l&&(clearTimeout(l),l=null),i=m,e.apply(this,p)):l||(l=setTimeout(()=>{l=null,i=Date.now(),o&&(e.apply(this,o),o=null)},h))}}function D(){const e=document.createElement("div");e.style.width="100px",e.style.height="100px",e.style.overflow="scroll",e.style.position="absolute",e.style.top="-9999px",document.body.appendChild(e);const s=e.offsetWidth-e.clientWidth;return document.body.removeChild(e),s}exports.flexible=P;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=(e={})=>{const{breakpoints:s=[768],layouts:l,basicLayout:i,scope:o,immediate:h=!1,orientationchange:d=!0,ratio:p,resizeOption:x,onInitialized:a}=e,b=s,t=l,E=i??(t==null?void 0:t.at(-1)),L="--local-scope-rem",T=N();let n=p;n&&(t==null?void 0:t.length)!==n.length&&t&&(n=[...n,...Array.from({length:t.length-n.length},()=>1)]);const W=m=>!t||!E?1:t.length-1===b.length?E/t[m]:1,f=()=>{(()=>{const y=window.innerWidth;let c=(window.innerWidth-T)/100,A=!1,g=0;if(t){for(let r=0;r<b.length;r++)if(y<=b[r]){c=c*W(r)*((n==null?void 0:n[r])??1),A=!0,g=r;break}A||(c=c*W(t.length-1)*((n==null?void 0:n[t.length-1])??1),g=t.length-1)}if(o)if(Array.isArray(o))o.forEach(r=>{const{element:w=document.documentElement,cssVarName:k=L,ratio:v}=r,S=(v==null?void 0:v[g])??(n==null?void 0:n[g])??1;w.style.setProperty(k,c*S+"px")});else{const{element:r=document.documentElement,cssVarName:w=L}=o;r.style.setProperty(w,c+"px")}else document.documentElement.style.fontSize=c+"px"})()};let u=f;if(x){const{type:m,delay:y=150}=x;m==="debounce"?u=B(f,y):m==="throttle"&&(u=D(f,y))}return h?(f(),requestAnimationFrame(()=>{a==null||a()})):window.addEventListener("load",()=>{f(),requestAnimationFrame(()=>{a==null||a()})}),window.addEventListener("resize",u),d&&screen.orientation.addEventListener("change",u),()=>{window.removeEventListener("resize",u),d&&screen.orientation.removeEventListener("change",u)}};function B(e,s){let l=null;return function(...i){const o=this;l&&clearTimeout(l),l=setTimeout(()=>{l=null,e.apply(o,i)},s)}}function D(e,s){let l=0,i=null,o=null;return function(...h){const d=Date.now(),p=s-(d-l);o=h,p<=0?(i&&(clearTimeout(i),i=null),l=d,e.apply(this,h)):i||(i=setTimeout(()=>{i=null,l=Date.now(),o&&(e.apply(this,o),o=null)},p))}}function N(){const e=document.createElement("div");e.style.width="100px",e.style.height="100px",e.style.overflow="scroll",e.style.position="absolute",e.style.top="-9999px",document.body.appendChild(e);const s=e.offsetWidth-e.clientWidth;return document.body.removeChild(e),s}exports.flexible=C;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["/**\n * 弹性布局函数的配置选项。\n */\nexport interface FlexibleOptions {\n /**\n * 一个以像素为单位的断点数组,从大到小排列。\n * 默认为 [768]。\n */\n breakpoints?: number[];\n /**\n * 一个与断点相对应的布局宽度数组。\n * 其项目数量必须比断点数组多一个。\n * 例如,如果 breakpoints 是 [768],则 layouts 可以是 [375, 1920],\n * 其中 375 是视口宽度 <= 768px 时的布局宽度,1920 是视口宽度 > 768px 时的布局宽度。\n */\n layouts?: number[];\n /**\n * 用作计算参考的基础布局宽度。\n * 仅在提供了 layouts 时有效。\n * 用作比例计算的基准布局宽度。\n * 默认为 layouts 数组中的最后一项 (layouts?.at(-1)),\n * 这通常代表最大的视口宽度。\n */\n basicLayout?: number;\n /**\n * 是否在初始化时立即应用布局。\n * 默认为 false。\n */\n immediate?: boolean;\n /**\n * 是否监听屏幕方向变化事件。\n * 默认为 true。\n */\n orientationchange?: boolean;\n\n /**\n * 是否在特定的作用域元素上设置 CSS 变量。\n * 默认为 false,表示在 document 元素上设置字体大小。\n * 如果提供一个对象,可以指定元素和 CSS 变量名。\n */\n scope?:\n | false\n | {\n /**\n * 设置 CSS 变量的作用域元素。\n * 默认为 document.documentElement。\n */\n element: HTMLElement;\n /**\n * 用于 rem 基础值的 CSS 变量名。\n * 默认为 \"--local-scope-rem\"。\n */\n cssVarName?: string;\n }\n | {\n /**\n * 设置 CSS 变量的作用域元素。\n * 默认为 document.documentElement。\n */\n element: HTMLElement;\n /**\n * 每个布局的比例因子数组,用于海报模式或自定义缩放。\n * 长度必须与 layouts 数组相同。\n * 默认为 [1, 1, ...] (无额外缩放)。\n */\n ratio?: number[];\n /**\n * 用于 rem 基础值的 CSS 变量名。\n * 默认为 \"--local-scope-rem\"。\n */\n cssVarName?: string;\n }[];\n\n /**\n * 每个布局的比例因子数组,用于海报模式或自定义缩放。\n * 长度必须与 layouts 数组相同。\n * 默认为 [1, 1, ...] (无额外缩放)。\n */\n ratio?: number[];\n /**\n * 是否在窗口大小调整时重新校准布局。\n * 因为宽度变化,但是css var没来得及变化导致出现滚动条,clientWidth和innerWidth不一致\n * 默认为 true。\n */\n recalibrate?: boolean;\n /**\n * 用于控制 resize 行为的选项。\n */\n resizeOption?:\n | {\n type: 'debounce' | 'throttle';\n delay?: number;\n }\n | false;\n onInitialized?: () => void;\n}\n\n/**\n * 初始化一个弹性布局系统,该系统会根据视口宽度设置一个用于 rem 单位的 CSS 变量,\n * 并根据断点自适应缩放。\n *\n * @param options - 弹性布局的配置选项\n * @returns 一个用于移除事件监听器的清理函数\n */\nexport const flexible = (options: FlexibleOptions = {}): (() => void) => {\n const {\n breakpoints: propBreakpoints = [768],\n layouts: propLayouts,\n basicLayout: propBasicLayout,\n scope,\n immediate = false,\n orientationchange = true,\n ratio: propRatio,\n recalibrate = true,\n resizeOption,\n onInitialized,\n } = options;\n const breakpoints = propBreakpoints;\n const layouts = propLayouts;\n const basicLayout = propBasicLayout ?? layouts?.at(-1);\n const defaultScopeCssVarName = '--local-scope-rem';\n // 对于相同设备来说,滚动条要么永远占据宽度,要么永远不占据宽度\n const isScrollbarPresent = getScrollbarWidth() > 0;\n\n // 确保 ratio 数组的长度与 layouts 匹配,默认为 1\n let ratio = propRatio;\n if (ratio) {\n if (layouts?.length !== ratio.length && layouts) {\n ratio = [...ratio, ...Array.from({ length: layouts.length - ratio.length }, () => 1)];\n }\n }\n\n /**\n * 计算特定断点的比例因子\n * @param index - 断点索引\n * @returns 比例因子,默认为 1\n */\n const getBreakpointRatio = (index: number): number => {\n if (!layouts || !basicLayout) return 1;\n if (layouts.length - 1 === breakpoints.length) {\n return basicLayout / layouts[index];\n }\n return 1; // 默认为 1 的比例因子\n };\n\n /**\n * 响应窗口大小变化并更新 CSS 变量\n */\n const responsive = (): void => {\n // 内部核心计算逻辑,可以被重复调用\n const recalculate = () => {\n const width = window.innerWidth; // 用于断点匹配\n const effectiveWidth = document.documentElement.clientWidth; // 用于rem计算\n\n let vw = effectiveWidth / 100;\n let matched = false;\n let matchedIndex = 0;\n if (layouts) {\n for (let i = 0; i < breakpoints.length; i++) {\n if (width <= breakpoints[i]) {\n vw = vw * getBreakpointRatio(i) * (ratio?.[i] ?? 1);\n matched = true;\n matchedIndex = i;\n break;\n }\n }\n if (!matched) {\n vw = vw * getBreakpointRatio(layouts.length - 1) * (ratio?.[layouts.length - 1] ?? 1);\n matchedIndex = layouts.length - 1;\n }\n }\n if (scope) {\n if (Array.isArray(scope)) {\n scope.forEach((item) => {\n const { element = document.documentElement, cssVarName = defaultScopeCssVarName, ratio: scopeRatio } = item;\n const computedRatio = scopeRatio?.[matchedIndex] ?? ratio?.[matchedIndex] ?? 1;\n element.style.setProperty(cssVarName, vw * computedRatio + 'px');\n });\n } else {\n const { element = document.documentElement, cssVarName = defaultScopeCssVarName } = scope;\n element.style.setProperty(cssVarName, vw + 'px');\n }\n } else {\n document.documentElement.style.fontSize = vw + 'px';\n }\n };\n\n // 第一次计算:使用当前的clientWidth值,这会触发浏览器的重绘\n recalculate();\n // 第二次计算:请求在浏览器下一次重绘前再次计算。\n // 此时,clientWidth已经是重排后的稳定值。\n if (recalibrate && isScrollbarPresent) {\n requestAnimationFrame(recalculate);\n }\n };\n\n let resizeHandler: () => void = responsive;\n if (resizeOption) {\n // 默认延迟150ms\n const { type, delay = 150 } = resizeOption;\n if (type === 'debounce') {\n resizeHandler = debounce(responsive, delay);\n } else if (type === 'throttle') {\n resizeHandler = throttle(responsive, delay);\n }\n }\n if (immediate) {\n responsive();\n requestAnimationFrame(() => {\n onInitialized?.();\n });\n } else {\n window.addEventListener('load', () => {\n responsive();\n requestAnimationFrame(() => {\n onInitialized?.();\n });\n });\n }\n window.addEventListener('resize', resizeHandler);\n if (orientationchange) {\n screen.orientation.addEventListener('change', resizeHandler);\n }\n // 返回清理函数\n return () => {\n window.removeEventListener('resize', resizeHandler);\n if (orientationchange) {\n screen.orientation.removeEventListener('change', resizeHandler);\n }\n };\n};\n\n/**\n * 防抖函数:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。\n * @param func 要执行的函数\n * @param wait 延迟时间(毫秒)\n * @returns 防抖后的函数\n */\nfunction debounce<F extends (...args: any[]) => any>(func: F, wait: number): F {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: any, ...args: Parameters<F>) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const context = this;\n if (timeout) {\n clearTimeout(timeout);\n }\n timeout = setTimeout(() => {\n timeout = null;\n func.apply(context, args);\n }, wait);\n } as F;\n}\n\n/**\n * 节流函数:限制 func 在 delay 时间内只执行一次,确保最后一次也能被执行\n * @param func 要执行的函数\n * @param delay 节流间隔(毫秒)\n * @returns 节流后的函数\n */\nfunction throttle<T extends (...args: any[]) => void>(func: T, delay: number): (...args: Parameters<T>) => void {\n let lastCallTime = 0;\n let timeout: ReturnType<typeof setTimeout> | null = null;\n let lastArgs: Parameters<T> | null = null;\n\n return function (...args: Parameters<T>) {\n const now = Date.now();\n const remaining = delay - (now - lastCallTime);\n lastArgs = args;\n\n if (remaining <= 0) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n lastCallTime = now;\n //@ts-ignore\n func.apply(this, args);\n } else if (!timeout) {\n timeout = setTimeout(() => {\n timeout = null;\n lastCallTime = Date.now();\n if (lastArgs) {\n //@ts-ignore\n func.apply(this, lastArgs);\n lastArgs = null;\n }\n }, remaining);\n }\n };\n}\n\n/**\n * 计算浏览器滚动条的宽度。\n * @returns {number} 滚动条的宽度(像素)\n */\nfunction getScrollbarWidth(): number {\n const scrollDiv = document.createElement('div');\n scrollDiv.style.width = '100px';\n scrollDiv.style.height = '100px';\n scrollDiv.style.overflow = 'scroll';\n scrollDiv.style.position = 'absolute';\n scrollDiv.style.top = '-9999px';\n document.body.appendChild(scrollDiv);\n const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;\n document.body.removeChild(scrollDiv);\n return scrollbarWidth;\n}\n"],"names":["flexible","options","propBreakpoints","propLayouts","propBasicLayout","scope","immediate","orientationchange","propRatio","recalibrate","resizeOption","onInitialized","breakpoints","layouts","basicLayout","defaultScopeCssVarName","isScrollbarPresent","getScrollbarWidth","ratio","getBreakpointRatio","index","responsive","recalculate","width","vw","matched","matchedIndex","i","item","element","cssVarName","scopeRatio","computedRatio","resizeHandler","type","delay","debounce","throttle","func","wait","timeout","args","context","lastCallTime","lastArgs","now","remaining","scrollDiv","scrollbarWidth"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["/**\n * 弹性布局函数的配置选项。\n */\nexport interface FlexibleOptions {\n /**\n * 一个以像素为单位的断点数组,从大到小排列。\n * 默认为 [768]。\n */\n breakpoints?: number[];\n /**\n * 一个与断点相对应的布局宽度数组。\n * 其项目数量必须比断点数组多一个。\n * 例如,如果 breakpoints 是 [768],则 layouts 可以是 [375, 1920],\n * 其中 375 是视口宽度 <= 768px 时的布局宽度,1920 是视口宽度 > 768px 时的布局宽度。\n */\n layouts?: number[];\n /**\n * 用作计算参考的基础布局宽度。\n * 仅在提供了 layouts 时有效。\n * 用作比例计算的基准布局宽度。\n * 默认为 layouts 数组中的最后一项 (layouts?.at(-1)),\n * 这通常代表最大的视口宽度。\n */\n basicLayout?: number;\n /**\n * 是否在初始化时立即应用布局。\n * 默认为 false。\n */\n immediate?: boolean;\n /**\n * 是否监听屏幕方向变化事件。\n * 默认为 true。\n */\n orientationchange?: boolean;\n\n /**\n * 是否在特定的作用域元素上设置 CSS 变量。\n * 默认为 false,表示在 document 元素上设置字体大小。\n * 如果提供一个对象,可以指定元素和 CSS 变量名。\n */\n scope?:\n | false\n | {\n /**\n * 设置 CSS 变量的作用域元素。\n * 默认为 document.documentElement。\n */\n element: HTMLElement;\n /**\n * 用于 rem 基础值的 CSS 变量名。\n * 默认为 \"--local-scope-rem\"。\n */\n cssVarName?: string;\n }\n | {\n /**\n * 设置 CSS 变量的作用域元素。\n * 默认为 document.documentElement。\n */\n element: HTMLElement;\n /**\n * 每个布局的比例因子数组,用于海报模式或自定义缩放。\n * 长度必须与 layouts 数组相同。\n * 默认为 [1, 1, ...] (无额外缩放)。\n */\n ratio?: number[];\n /**\n * 用于 rem 基础值的 CSS 变量名。\n * 默认为 \"--local-scope-rem\"。\n */\n cssVarName?: string;\n }[];\n\n /**\n * 每个布局的比例因子数组,用于海报模式或自定义缩放。\n * 长度必须与 layouts 数组相同。\n * 默认为 [1, 1, ...] (无额外缩放)。\n */\n ratio?: number[];\n /**\n * 用于控制 resize 行为的选项。\n */\n resizeOption?:\n | {\n type: 'debounce' | 'throttle';\n delay?: number;\n }\n | false;\n onInitialized?: () => void;\n}\n\n/**\n * 初始化一个弹性布局系统,该系统会根据视口宽度设置一个用于 rem 单位的 CSS 变量,\n * 并根据断点自适应缩放。\n *\n * @param options - 弹性布局的配置选项\n * @returns 一个用于移除事件监听器的清理函数\n */\nexport const flexible = (options: FlexibleOptions = {}): (() => void) => {\n const {\n breakpoints: propBreakpoints = [768],\n layouts: propLayouts,\n basicLayout: propBasicLayout,\n scope,\n immediate = false,\n orientationchange = true,\n ratio: propRatio,\n resizeOption,\n onInitialized,\n } = options;\n const breakpoints = propBreakpoints;\n const layouts = propLayouts;\n const basicLayout = propBasicLayout ?? layouts?.at(-1);\n const defaultScopeCssVarName = '--local-scope-rem';\n // 对于相同设备来说,滚动条要么永远占据宽度,要么永远不占据宽度\n const scrollbarWidth = getScrollbarWidth();\n\n // 确保 ratio 数组的长度与 layouts 匹配,默认为 1\n let ratio = propRatio;\n if (ratio) {\n if (layouts?.length !== ratio.length && layouts) {\n ratio = [...ratio, ...Array.from({ length: layouts.length - ratio.length }, () => 1)];\n }\n }\n\n /**\n * 计算特定断点的比例因子\n * @param index - 断点索引\n * @returns 比例因子,默认为 1\n */\n const getBreakpointRatio = (index: number): number => {\n if (!layouts || !basicLayout) return 1;\n if (layouts.length - 1 === breakpoints.length) {\n return basicLayout / layouts[index];\n }\n return 1; // 默认为 1 的比例因子\n };\n\n /**\n * 响应窗口大小变化并更新 CSS 变量\n */\n const responsive = (): void => {\n // 内部核心计算逻辑,可以被重复调用\n const recalculate = () => {\n const width = window.innerWidth; // 用于断点匹配\n // const effectiveWidth = document.documentElement.clientWidth; // 用于rem计算\n //TODO: ?没办法去判断滚动条的状态\n const effectiveWidth = window.innerWidth - scrollbarWidth;\n\n let vw = effectiveWidth / 100;\n let matched = false;\n let matchedIndex = 0;\n if (layouts) {\n for (let i = 0; i < breakpoints.length; i++) {\n if (width <= breakpoints[i]) {\n vw = vw * getBreakpointRatio(i) * (ratio?.[i] ?? 1);\n matched = true;\n matchedIndex = i;\n break;\n }\n }\n if (!matched) {\n vw = vw * getBreakpointRatio(layouts.length - 1) * (ratio?.[layouts.length - 1] ?? 1);\n matchedIndex = layouts.length - 1;\n }\n }\n if (scope) {\n if (Array.isArray(scope)) {\n scope.forEach((item) => {\n const { element = document.documentElement, cssVarName = defaultScopeCssVarName, ratio: scopeRatio } = item;\n const computedRatio = scopeRatio?.[matchedIndex] ?? ratio?.[matchedIndex] ?? 1;\n element.style.setProperty(cssVarName, vw * computedRatio + 'px');\n });\n } else {\n const { element = document.documentElement, cssVarName = defaultScopeCssVarName } = scope;\n element.style.setProperty(cssVarName, vw + 'px');\n }\n } else {\n document.documentElement.style.fontSize = vw + 'px';\n }\n };\n\n // 第一次计算:使用当前的clientWidth值,这会触发浏览器的重绘\n recalculate();\n // 第二次计算:请求在浏览器下一次重绘前再次计算。\n // 此时,clientWidth已经是重排后的稳定值。\n // if (recalibrate && isScrollbarPresent) {\n // requestAnimationFrame(recalculate);\n // }\n };\n\n let resizeHandler: () => void = responsive;\n if (resizeOption) {\n // 默认延迟150ms\n const { type, delay = 150 } = resizeOption;\n if (type === 'debounce') {\n resizeHandler = debounce(responsive, delay);\n } else if (type === 'throttle') {\n resizeHandler = throttle(responsive, delay);\n }\n }\n if (immediate) {\n responsive();\n requestAnimationFrame(() => {\n onInitialized?.();\n });\n } else {\n window.addEventListener('load', () => {\n responsive();\n requestAnimationFrame(() => {\n onInitialized?.();\n });\n });\n }\n window.addEventListener('resize', resizeHandler);\n if (orientationchange) {\n screen.orientation.addEventListener('change', resizeHandler);\n }\n // 返回清理函数\n return () => {\n window.removeEventListener('resize', resizeHandler);\n if (orientationchange) {\n screen.orientation.removeEventListener('change', resizeHandler);\n }\n };\n};\n\n/**\n * 防抖函数:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。\n * @param func 要执行的函数\n * @param wait 延迟时间(毫秒)\n * @returns 防抖后的函数\n */\nfunction debounce<F extends (...args: any[]) => any>(func: F, wait: number): F {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: any, ...args: Parameters<F>) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const context = this;\n if (timeout) {\n clearTimeout(timeout);\n }\n timeout = setTimeout(() => {\n timeout = null;\n func.apply(context, args);\n }, wait);\n } as F;\n}\n\n/**\n * 节流函数:限制 func 在 delay 时间内只执行一次,确保最后一次也能被执行\n * @param func 要执行的函数\n * @param delay 节流间隔(毫秒)\n * @returns 节流后的函数\n */\nfunction throttle<T extends (...args: any[]) => void>(func: T, delay: number): (...args: Parameters<T>) => void {\n let lastCallTime = 0;\n let timeout: ReturnType<typeof setTimeout> | null = null;\n let lastArgs: Parameters<T> | null = null;\n\n return function (...args: Parameters<T>) {\n const now = Date.now();\n const remaining = delay - (now - lastCallTime);\n lastArgs = args;\n\n if (remaining <= 0) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n lastCallTime = now;\n //@ts-ignore\n func.apply(this, args);\n } else if (!timeout) {\n timeout = setTimeout(() => {\n timeout = null;\n lastCallTime = Date.now();\n if (lastArgs) {\n //@ts-ignore\n func.apply(this, lastArgs);\n lastArgs = null;\n }\n }, remaining);\n }\n };\n}\n\n/**\n * 计算浏览器滚动条的宽度。\n * @returns {number} 滚动条的宽度(像素)\n */\nfunction getScrollbarWidth(): number {\n const scrollDiv = document.createElement('div');\n scrollDiv.style.width = '100px';\n scrollDiv.style.height = '100px';\n scrollDiv.style.overflow = 'scroll';\n scrollDiv.style.position = 'absolute';\n scrollDiv.style.top = '-9999px';\n document.body.appendChild(scrollDiv);\n const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;\n document.body.removeChild(scrollDiv);\n return scrollbarWidth;\n}\n"],"names":["flexible","options","propBreakpoints","propLayouts","propBasicLayout","scope","immediate","orientationchange","propRatio","resizeOption","onInitialized","breakpoints","layouts","basicLayout","defaultScopeCssVarName","scrollbarWidth","getScrollbarWidth","ratio","getBreakpointRatio","index","responsive","width","vw","matched","matchedIndex","i","item","element","cssVarName","scopeRatio","computedRatio","resizeHandler","type","delay","debounce","throttle","func","wait","timeout","args","context","lastCallTime","lastArgs","now","remaining","scrollDiv"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -81,12 +81,6 @@ export declare interface FlexibleOptions {
81
81
  * 默认为 [1, 1, ...] (无额外缩放)。
82
82
  */
83
83
  ratio?: number[];
84
- /**
85
- * 是否在窗口大小调整时重新校准布局。
86
- * 因为宽度变化,但是css var没来得及变化导致出现滚动条,clientWidth和innerWidth不一致
87
- * 默认为 true。
88
- */
89
- recalibrate?: boolean;
90
84
  /**
91
85
  * 用于控制 resize 行为的选项。
92
86
  */
package/dist/index.js CHANGED
@@ -1,61 +1,59 @@
1
- const N = (e = {}) => {
1
+ const V = (e = {}) => {
2
2
  const {
3
3
  breakpoints: s = [768],
4
4
  layouts: i,
5
5
  basicLayout: l,
6
6
  scope: o,
7
- immediate: p = !1,
8
- orientationchange: m = !0,
9
- ratio: h,
10
- recalibrate: k = !0,
11
- resizeOption: E,
12
- onInitialized: u
13
- } = e, b = s, t = i, x = l ?? (t == null ? void 0 : t.at(-1)), L = "--local-scope-rem", T = D() > 0;
14
- let n = h;
7
+ immediate: h = !1,
8
+ orientationchange: d = !0,
9
+ ratio: p,
10
+ resizeOption: x,
11
+ onInitialized: a
12
+ } = e, w = s, t = i, E = l ?? (t == null ? void 0 : t.at(-1)), L = "--local-scope-rem", k = N();
13
+ let n = p;
15
14
  n && (t == null ? void 0 : t.length) !== n.length && t && (n = [...n, ...Array.from({ length: t.length - n.length }, () => 1)]);
16
- const W = (c) => !t || !x ? 1 : t.length - 1 === b.length ? x / t[c] : 1, f = () => {
17
- const c = () => {
15
+ const W = (f) => !t || !E ? 1 : t.length - 1 === w.length ? E / t[f] : 1, m = () => {
16
+ (() => {
18
17
  const y = window.innerWidth;
19
- let a = document.documentElement.clientWidth / 100, A = !1, g = 0;
18
+ let c = (window.innerWidth - k) / 100, A = !1, g = 0;
20
19
  if (t) {
21
- for (let r = 0; r < b.length; r++)
22
- if (y <= b[r]) {
23
- a = a * W(r) * ((n == null ? void 0 : n[r]) ?? 1), A = !0, g = r;
20
+ for (let r = 0; r < w.length; r++)
21
+ if (y <= w[r]) {
22
+ c = c * W(r) * ((n == null ? void 0 : n[r]) ?? 1), A = !0, g = r;
24
23
  break;
25
24
  }
26
- A || (a = a * W(t.length - 1) * ((n == null ? void 0 : n[t.length - 1]) ?? 1), g = t.length - 1);
25
+ A || (c = c * W(t.length - 1) * ((n == null ? void 0 : n[t.length - 1]) ?? 1), g = t.length - 1);
27
26
  }
28
27
  if (o)
29
28
  if (Array.isArray(o))
30
29
  o.forEach((r) => {
31
- const { element: v = document.documentElement, cssVarName: C = L, ratio: w } = r, S = (w == null ? void 0 : w[g]) ?? (n == null ? void 0 : n[g]) ?? 1;
32
- v.style.setProperty(C, a * S + "px");
30
+ const { element: v = document.documentElement, cssVarName: T = L, ratio: b } = r, C = (b == null ? void 0 : b[g]) ?? (n == null ? void 0 : n[g]) ?? 1;
31
+ v.style.setProperty(T, c * C + "px");
33
32
  });
34
33
  else {
35
34
  const { element: r = document.documentElement, cssVarName: v = L } = o;
36
- r.style.setProperty(v, a + "px");
35
+ r.style.setProperty(v, c + "px");
37
36
  }
38
37
  else
39
- document.documentElement.style.fontSize = a + "px";
40
- };
41
- c(), k && T && requestAnimationFrame(c);
38
+ document.documentElement.style.fontSize = c + "px";
39
+ })();
42
40
  };
43
- let d = f;
44
- if (E) {
45
- const { type: c, delay: y = 150 } = E;
46
- c === "debounce" ? d = q(f, y) : c === "throttle" && (d = B(f, y));
41
+ let u = m;
42
+ if (x) {
43
+ const { type: f, delay: y = 150 } = x;
44
+ f === "debounce" ? u = B(m, y) : f === "throttle" && (u = D(m, y));
47
45
  }
48
- return p ? (f(), requestAnimationFrame(() => {
49
- u == null || u();
46
+ return h ? (m(), requestAnimationFrame(() => {
47
+ a == null || a();
50
48
  })) : window.addEventListener("load", () => {
51
- f(), requestAnimationFrame(() => {
52
- u == null || u();
49
+ m(), requestAnimationFrame(() => {
50
+ a == null || a();
53
51
  });
54
- }), window.addEventListener("resize", d), m && screen.orientation.addEventListener("change", d), () => {
55
- window.removeEventListener("resize", d), m && screen.orientation.removeEventListener("change", d);
52
+ }), window.addEventListener("resize", u), d && screen.orientation.addEventListener("change", u), () => {
53
+ window.removeEventListener("resize", u), d && screen.orientation.removeEventListener("change", u);
56
54
  };
57
55
  };
58
- function q(e, s) {
56
+ function B(e, s) {
59
57
  let i = null;
60
58
  return function(...l) {
61
59
  const o = this;
@@ -64,22 +62,22 @@ function q(e, s) {
64
62
  }, s);
65
63
  };
66
64
  }
67
- function B(e, s) {
65
+ function D(e, s) {
68
66
  let i = 0, l = null, o = null;
69
- return function(...p) {
70
- const m = Date.now(), h = s - (m - i);
71
- o = p, h <= 0 ? (l && (clearTimeout(l), l = null), i = m, e.apply(this, p)) : l || (l = setTimeout(() => {
67
+ return function(...h) {
68
+ const d = Date.now(), p = s - (d - i);
69
+ o = h, p <= 0 ? (l && (clearTimeout(l), l = null), i = d, e.apply(this, h)) : l || (l = setTimeout(() => {
72
70
  l = null, i = Date.now(), o && (e.apply(this, o), o = null);
73
- }, h));
71
+ }, p));
74
72
  };
75
73
  }
76
- function D() {
74
+ function N() {
77
75
  const e = document.createElement("div");
78
76
  e.style.width = "100px", e.style.height = "100px", e.style.overflow = "scroll", e.style.position = "absolute", e.style.top = "-9999px", document.body.appendChild(e);
79
77
  const s = e.offsetWidth - e.clientWidth;
80
78
  return document.body.removeChild(e), s;
81
79
  }
82
80
  export {
83
- N as flexible
81
+ V as flexible
84
82
  };
85
83
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * 弹性布局函数的配置选项。\n */\nexport interface FlexibleOptions {\n /**\n * 一个以像素为单位的断点数组,从大到小排列。\n * 默认为 [768]。\n */\n breakpoints?: number[];\n /**\n * 一个与断点相对应的布局宽度数组。\n * 其项目数量必须比断点数组多一个。\n * 例如,如果 breakpoints 是 [768],则 layouts 可以是 [375, 1920],\n * 其中 375 是视口宽度 <= 768px 时的布局宽度,1920 是视口宽度 > 768px 时的布局宽度。\n */\n layouts?: number[];\n /**\n * 用作计算参考的基础布局宽度。\n * 仅在提供了 layouts 时有效。\n * 用作比例计算的基准布局宽度。\n * 默认为 layouts 数组中的最后一项 (layouts?.at(-1)),\n * 这通常代表最大的视口宽度。\n */\n basicLayout?: number;\n /**\n * 是否在初始化时立即应用布局。\n * 默认为 false。\n */\n immediate?: boolean;\n /**\n * 是否监听屏幕方向变化事件。\n * 默认为 true。\n */\n orientationchange?: boolean;\n\n /**\n * 是否在特定的作用域元素上设置 CSS 变量。\n * 默认为 false,表示在 document 元素上设置字体大小。\n * 如果提供一个对象,可以指定元素和 CSS 变量名。\n */\n scope?:\n | false\n | {\n /**\n * 设置 CSS 变量的作用域元素。\n * 默认为 document.documentElement。\n */\n element: HTMLElement;\n /**\n * 用于 rem 基础值的 CSS 变量名。\n * 默认为 \"--local-scope-rem\"。\n */\n cssVarName?: string;\n }\n | {\n /**\n * 设置 CSS 变量的作用域元素。\n * 默认为 document.documentElement。\n */\n element: HTMLElement;\n /**\n * 每个布局的比例因子数组,用于海报模式或自定义缩放。\n * 长度必须与 layouts 数组相同。\n * 默认为 [1, 1, ...] (无额外缩放)。\n */\n ratio?: number[];\n /**\n * 用于 rem 基础值的 CSS 变量名。\n * 默认为 \"--local-scope-rem\"。\n */\n cssVarName?: string;\n }[];\n\n /**\n * 每个布局的比例因子数组,用于海报模式或自定义缩放。\n * 长度必须与 layouts 数组相同。\n * 默认为 [1, 1, ...] (无额外缩放)。\n */\n ratio?: number[];\n /**\n * 是否在窗口大小调整时重新校准布局。\n * 因为宽度变化,但是css var没来得及变化导致出现滚动条,clientWidth和innerWidth不一致\n * 默认为 true。\n */\n recalibrate?: boolean;\n /**\n * 用于控制 resize 行为的选项。\n */\n resizeOption?:\n | {\n type: 'debounce' | 'throttle';\n delay?: number;\n }\n | false;\n onInitialized?: () => void;\n}\n\n/**\n * 初始化一个弹性布局系统,该系统会根据视口宽度设置一个用于 rem 单位的 CSS 变量,\n * 并根据断点自适应缩放。\n *\n * @param options - 弹性布局的配置选项\n * @returns 一个用于移除事件监听器的清理函数\n */\nexport const flexible = (options: FlexibleOptions = {}): (() => void) => {\n const {\n breakpoints: propBreakpoints = [768],\n layouts: propLayouts,\n basicLayout: propBasicLayout,\n scope,\n immediate = false,\n orientationchange = true,\n ratio: propRatio,\n recalibrate = true,\n resizeOption,\n onInitialized,\n } = options;\n const breakpoints = propBreakpoints;\n const layouts = propLayouts;\n const basicLayout = propBasicLayout ?? layouts?.at(-1);\n const defaultScopeCssVarName = '--local-scope-rem';\n // 对于相同设备来说,滚动条要么永远占据宽度,要么永远不占据宽度\n const isScrollbarPresent = getScrollbarWidth() > 0;\n\n // 确保 ratio 数组的长度与 layouts 匹配,默认为 1\n let ratio = propRatio;\n if (ratio) {\n if (layouts?.length !== ratio.length && layouts) {\n ratio = [...ratio, ...Array.from({ length: layouts.length - ratio.length }, () => 1)];\n }\n }\n\n /**\n * 计算特定断点的比例因子\n * @param index - 断点索引\n * @returns 比例因子,默认为 1\n */\n const getBreakpointRatio = (index: number): number => {\n if (!layouts || !basicLayout) return 1;\n if (layouts.length - 1 === breakpoints.length) {\n return basicLayout / layouts[index];\n }\n return 1; // 默认为 1 的比例因子\n };\n\n /**\n * 响应窗口大小变化并更新 CSS 变量\n */\n const responsive = (): void => {\n // 内部核心计算逻辑,可以被重复调用\n const recalculate = () => {\n const width = window.innerWidth; // 用于断点匹配\n const effectiveWidth = document.documentElement.clientWidth; // 用于rem计算\n\n let vw = effectiveWidth / 100;\n let matched = false;\n let matchedIndex = 0;\n if (layouts) {\n for (let i = 0; i < breakpoints.length; i++) {\n if (width <= breakpoints[i]) {\n vw = vw * getBreakpointRatio(i) * (ratio?.[i] ?? 1);\n matched = true;\n matchedIndex = i;\n break;\n }\n }\n if (!matched) {\n vw = vw * getBreakpointRatio(layouts.length - 1) * (ratio?.[layouts.length - 1] ?? 1);\n matchedIndex = layouts.length - 1;\n }\n }\n if (scope) {\n if (Array.isArray(scope)) {\n scope.forEach((item) => {\n const { element = document.documentElement, cssVarName = defaultScopeCssVarName, ratio: scopeRatio } = item;\n const computedRatio = scopeRatio?.[matchedIndex] ?? ratio?.[matchedIndex] ?? 1;\n element.style.setProperty(cssVarName, vw * computedRatio + 'px');\n });\n } else {\n const { element = document.documentElement, cssVarName = defaultScopeCssVarName } = scope;\n element.style.setProperty(cssVarName, vw + 'px');\n }\n } else {\n document.documentElement.style.fontSize = vw + 'px';\n }\n };\n\n // 第一次计算:使用当前的clientWidth值,这会触发浏览器的重绘\n recalculate();\n // 第二次计算:请求在浏览器下一次重绘前再次计算。\n // 此时,clientWidth已经是重排后的稳定值。\n if (recalibrate && isScrollbarPresent) {\n requestAnimationFrame(recalculate);\n }\n };\n\n let resizeHandler: () => void = responsive;\n if (resizeOption) {\n // 默认延迟150ms\n const { type, delay = 150 } = resizeOption;\n if (type === 'debounce') {\n resizeHandler = debounce(responsive, delay);\n } else if (type === 'throttle') {\n resizeHandler = throttle(responsive, delay);\n }\n }\n if (immediate) {\n responsive();\n requestAnimationFrame(() => {\n onInitialized?.();\n });\n } else {\n window.addEventListener('load', () => {\n responsive();\n requestAnimationFrame(() => {\n onInitialized?.();\n });\n });\n }\n window.addEventListener('resize', resizeHandler);\n if (orientationchange) {\n screen.orientation.addEventListener('change', resizeHandler);\n }\n // 返回清理函数\n return () => {\n window.removeEventListener('resize', resizeHandler);\n if (orientationchange) {\n screen.orientation.removeEventListener('change', resizeHandler);\n }\n };\n};\n\n/**\n * 防抖函数:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。\n * @param func 要执行的函数\n * @param wait 延迟时间(毫秒)\n * @returns 防抖后的函数\n */\nfunction debounce<F extends (...args: any[]) => any>(func: F, wait: number): F {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: any, ...args: Parameters<F>) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const context = this;\n if (timeout) {\n clearTimeout(timeout);\n }\n timeout = setTimeout(() => {\n timeout = null;\n func.apply(context, args);\n }, wait);\n } as F;\n}\n\n/**\n * 节流函数:限制 func 在 delay 时间内只执行一次,确保最后一次也能被执行\n * @param func 要执行的函数\n * @param delay 节流间隔(毫秒)\n * @returns 节流后的函数\n */\nfunction throttle<T extends (...args: any[]) => void>(func: T, delay: number): (...args: Parameters<T>) => void {\n let lastCallTime = 0;\n let timeout: ReturnType<typeof setTimeout> | null = null;\n let lastArgs: Parameters<T> | null = null;\n\n return function (...args: Parameters<T>) {\n const now = Date.now();\n const remaining = delay - (now - lastCallTime);\n lastArgs = args;\n\n if (remaining <= 0) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n lastCallTime = now;\n //@ts-ignore\n func.apply(this, args);\n } else if (!timeout) {\n timeout = setTimeout(() => {\n timeout = null;\n lastCallTime = Date.now();\n if (lastArgs) {\n //@ts-ignore\n func.apply(this, lastArgs);\n lastArgs = null;\n }\n }, remaining);\n }\n };\n}\n\n/**\n * 计算浏览器滚动条的宽度。\n * @returns {number} 滚动条的宽度(像素)\n */\nfunction getScrollbarWidth(): number {\n const scrollDiv = document.createElement('div');\n scrollDiv.style.width = '100px';\n scrollDiv.style.height = '100px';\n scrollDiv.style.overflow = 'scroll';\n scrollDiv.style.position = 'absolute';\n scrollDiv.style.top = '-9999px';\n document.body.appendChild(scrollDiv);\n const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;\n document.body.removeChild(scrollDiv);\n return scrollbarWidth;\n}\n"],"names":["flexible","options","propBreakpoints","propLayouts","propBasicLayout","scope","immediate","orientationchange","propRatio","recalibrate","resizeOption","onInitialized","breakpoints","layouts","basicLayout","defaultScopeCssVarName","isScrollbarPresent","getScrollbarWidth","ratio","getBreakpointRatio","index","responsive","recalculate","width","vw","matched","matchedIndex","i","item","element","cssVarName","scopeRatio","computedRatio","resizeHandler","type","delay","debounce","throttle","func","wait","timeout","args","context","lastCallTime","lastArgs","now","remaining","scrollDiv","scrollbarWidth"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * 弹性布局函数的配置选项。\n */\nexport interface FlexibleOptions {\n /**\n * 一个以像素为单位的断点数组,从大到小排列。\n * 默认为 [768]。\n */\n breakpoints?: number[];\n /**\n * 一个与断点相对应的布局宽度数组。\n * 其项目数量必须比断点数组多一个。\n * 例如,如果 breakpoints 是 [768],则 layouts 可以是 [375, 1920],\n * 其中 375 是视口宽度 <= 768px 时的布局宽度,1920 是视口宽度 > 768px 时的布局宽度。\n */\n layouts?: number[];\n /**\n * 用作计算参考的基础布局宽度。\n * 仅在提供了 layouts 时有效。\n * 用作比例计算的基准布局宽度。\n * 默认为 layouts 数组中的最后一项 (layouts?.at(-1)),\n * 这通常代表最大的视口宽度。\n */\n basicLayout?: number;\n /**\n * 是否在初始化时立即应用布局。\n * 默认为 false。\n */\n immediate?: boolean;\n /**\n * 是否监听屏幕方向变化事件。\n * 默认为 true。\n */\n orientationchange?: boolean;\n\n /**\n * 是否在特定的作用域元素上设置 CSS 变量。\n * 默认为 false,表示在 document 元素上设置字体大小。\n * 如果提供一个对象,可以指定元素和 CSS 变量名。\n */\n scope?:\n | false\n | {\n /**\n * 设置 CSS 变量的作用域元素。\n * 默认为 document.documentElement。\n */\n element: HTMLElement;\n /**\n * 用于 rem 基础值的 CSS 变量名。\n * 默认为 \"--local-scope-rem\"。\n */\n cssVarName?: string;\n }\n | {\n /**\n * 设置 CSS 变量的作用域元素。\n * 默认为 document.documentElement。\n */\n element: HTMLElement;\n /**\n * 每个布局的比例因子数组,用于海报模式或自定义缩放。\n * 长度必须与 layouts 数组相同。\n * 默认为 [1, 1, ...] (无额外缩放)。\n */\n ratio?: number[];\n /**\n * 用于 rem 基础值的 CSS 变量名。\n * 默认为 \"--local-scope-rem\"。\n */\n cssVarName?: string;\n }[];\n\n /**\n * 每个布局的比例因子数组,用于海报模式或自定义缩放。\n * 长度必须与 layouts 数组相同。\n * 默认为 [1, 1, ...] (无额外缩放)。\n */\n ratio?: number[];\n /**\n * 用于控制 resize 行为的选项。\n */\n resizeOption?:\n | {\n type: 'debounce' | 'throttle';\n delay?: number;\n }\n | false;\n onInitialized?: () => void;\n}\n\n/**\n * 初始化一个弹性布局系统,该系统会根据视口宽度设置一个用于 rem 单位的 CSS 变量,\n * 并根据断点自适应缩放。\n *\n * @param options - 弹性布局的配置选项\n * @returns 一个用于移除事件监听器的清理函数\n */\nexport const flexible = (options: FlexibleOptions = {}): (() => void) => {\n const {\n breakpoints: propBreakpoints = [768],\n layouts: propLayouts,\n basicLayout: propBasicLayout,\n scope,\n immediate = false,\n orientationchange = true,\n ratio: propRatio,\n resizeOption,\n onInitialized,\n } = options;\n const breakpoints = propBreakpoints;\n const layouts = propLayouts;\n const basicLayout = propBasicLayout ?? layouts?.at(-1);\n const defaultScopeCssVarName = '--local-scope-rem';\n // 对于相同设备来说,滚动条要么永远占据宽度,要么永远不占据宽度\n const scrollbarWidth = getScrollbarWidth();\n\n // 确保 ratio 数组的长度与 layouts 匹配,默认为 1\n let ratio = propRatio;\n if (ratio) {\n if (layouts?.length !== ratio.length && layouts) {\n ratio = [...ratio, ...Array.from({ length: layouts.length - ratio.length }, () => 1)];\n }\n }\n\n /**\n * 计算特定断点的比例因子\n * @param index - 断点索引\n * @returns 比例因子,默认为 1\n */\n const getBreakpointRatio = (index: number): number => {\n if (!layouts || !basicLayout) return 1;\n if (layouts.length - 1 === breakpoints.length) {\n return basicLayout / layouts[index];\n }\n return 1; // 默认为 1 的比例因子\n };\n\n /**\n * 响应窗口大小变化并更新 CSS 变量\n */\n const responsive = (): void => {\n // 内部核心计算逻辑,可以被重复调用\n const recalculate = () => {\n const width = window.innerWidth; // 用于断点匹配\n // const effectiveWidth = document.documentElement.clientWidth; // 用于rem计算\n //TODO: ?没办法去判断滚动条的状态\n const effectiveWidth = window.innerWidth - scrollbarWidth;\n\n let vw = effectiveWidth / 100;\n let matched = false;\n let matchedIndex = 0;\n if (layouts) {\n for (let i = 0; i < breakpoints.length; i++) {\n if (width <= breakpoints[i]) {\n vw = vw * getBreakpointRatio(i) * (ratio?.[i] ?? 1);\n matched = true;\n matchedIndex = i;\n break;\n }\n }\n if (!matched) {\n vw = vw * getBreakpointRatio(layouts.length - 1) * (ratio?.[layouts.length - 1] ?? 1);\n matchedIndex = layouts.length - 1;\n }\n }\n if (scope) {\n if (Array.isArray(scope)) {\n scope.forEach((item) => {\n const { element = document.documentElement, cssVarName = defaultScopeCssVarName, ratio: scopeRatio } = item;\n const computedRatio = scopeRatio?.[matchedIndex] ?? ratio?.[matchedIndex] ?? 1;\n element.style.setProperty(cssVarName, vw * computedRatio + 'px');\n });\n } else {\n const { element = document.documentElement, cssVarName = defaultScopeCssVarName } = scope;\n element.style.setProperty(cssVarName, vw + 'px');\n }\n } else {\n document.documentElement.style.fontSize = vw + 'px';\n }\n };\n\n // 第一次计算:使用当前的clientWidth值,这会触发浏览器的重绘\n recalculate();\n // 第二次计算:请求在浏览器下一次重绘前再次计算。\n // 此时,clientWidth已经是重排后的稳定值。\n // if (recalibrate && isScrollbarPresent) {\n // requestAnimationFrame(recalculate);\n // }\n };\n\n let resizeHandler: () => void = responsive;\n if (resizeOption) {\n // 默认延迟150ms\n const { type, delay = 150 } = resizeOption;\n if (type === 'debounce') {\n resizeHandler = debounce(responsive, delay);\n } else if (type === 'throttle') {\n resizeHandler = throttle(responsive, delay);\n }\n }\n if (immediate) {\n responsive();\n requestAnimationFrame(() => {\n onInitialized?.();\n });\n } else {\n window.addEventListener('load', () => {\n responsive();\n requestAnimationFrame(() => {\n onInitialized?.();\n });\n });\n }\n window.addEventListener('resize', resizeHandler);\n if (orientationchange) {\n screen.orientation.addEventListener('change', resizeHandler);\n }\n // 返回清理函数\n return () => {\n window.removeEventListener('resize', resizeHandler);\n if (orientationchange) {\n screen.orientation.removeEventListener('change', resizeHandler);\n }\n };\n};\n\n/**\n * 防抖函数:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。\n * @param func 要执行的函数\n * @param wait 延迟时间(毫秒)\n * @returns 防抖后的函数\n */\nfunction debounce<F extends (...args: any[]) => any>(func: F, wait: number): F {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n\n return function (this: any, ...args: Parameters<F>) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const context = this;\n if (timeout) {\n clearTimeout(timeout);\n }\n timeout = setTimeout(() => {\n timeout = null;\n func.apply(context, args);\n }, wait);\n } as F;\n}\n\n/**\n * 节流函数:限制 func 在 delay 时间内只执行一次,确保最后一次也能被执行\n * @param func 要执行的函数\n * @param delay 节流间隔(毫秒)\n * @returns 节流后的函数\n */\nfunction throttle<T extends (...args: any[]) => void>(func: T, delay: number): (...args: Parameters<T>) => void {\n let lastCallTime = 0;\n let timeout: ReturnType<typeof setTimeout> | null = null;\n let lastArgs: Parameters<T> | null = null;\n\n return function (...args: Parameters<T>) {\n const now = Date.now();\n const remaining = delay - (now - lastCallTime);\n lastArgs = args;\n\n if (remaining <= 0) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n lastCallTime = now;\n //@ts-ignore\n func.apply(this, args);\n } else if (!timeout) {\n timeout = setTimeout(() => {\n timeout = null;\n lastCallTime = Date.now();\n if (lastArgs) {\n //@ts-ignore\n func.apply(this, lastArgs);\n lastArgs = null;\n }\n }, remaining);\n }\n };\n}\n\n/**\n * 计算浏览器滚动条的宽度。\n * @returns {number} 滚动条的宽度(像素)\n */\nfunction getScrollbarWidth(): number {\n const scrollDiv = document.createElement('div');\n scrollDiv.style.width = '100px';\n scrollDiv.style.height = '100px';\n scrollDiv.style.overflow = 'scroll';\n scrollDiv.style.position = 'absolute';\n scrollDiv.style.top = '-9999px';\n document.body.appendChild(scrollDiv);\n const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;\n document.body.removeChild(scrollDiv);\n return scrollbarWidth;\n}\n"],"names":["flexible","options","propBreakpoints","propLayouts","propBasicLayout","scope","immediate","orientationchange","propRatio","resizeOption","onInitialized","breakpoints","layouts","basicLayout","defaultScopeCssVarName","scrollbarWidth","getScrollbarWidth","ratio","getBreakpointRatio","index","responsive","width","vw","matched","matchedIndex","i","item","element","cssVarName","scopeRatio","computedRatio","resizeHandler","type","delay","debounce","throttle","func","wait","timeout","args","context","lastCallTime","lastArgs","now","remaining","scrollDiv"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cherrywind/flexible",
3
- "version": "0.0.5-alpha.1",
3
+ "version": "0.0.5-alpha.2",
4
4
  "private": false,
5
5
  "keywords": [
6
6
  "flexible"