这个工具类主要监听元素大小变化的工具类。

    1. import ResizeObserver from 'resize-observer-polyfill';
    2. // 如果不是页面应用,就没必要监听窗口变化
    3. const isServer = typeof window === 'undefined';
    4. // 当监听到元素Size变化后,执行的方法
    5. /* istanbul ignore next */
    6. function resizeHandler(entries: any[]) {
    7. // 循环匹配的元素
    8. for (const entry of entries) {
    9. // 将元素的__resizeListeners__字段下的方法都执行一遍
    10. const listeners = entry.target.__resizeListeners__ || [];
    11. if (listeners.length) {
    12. listeners.forEach((fn: () => any) => {
    13. fn();
    14. });
    15. }
    16. }
    17. }
    18. // 添加元素Size变化后的监听方法
    19. /* istanbul ignore next */
    20. export function addResizeListener(element: any, fn: () => any) {
    21. // 如果不是页面应用就返回
    22. if (isServer) return;
    23. // 如果元素的__resizeListeners__字段不存在,就说明还没有注册resize-observer-polyfill
    24. if (!element.__resizeListeners__) {
    25. // 设置该字段
    26. element.__resizeListeners__ = [];
    27. // 在元素的__ro__字段上创建一个resize-observer-polyfill
    28. element.__ro__ = new ResizeObserver(resizeHandler);
    29. // 并启动元素的__ro__监听
    30. element.__ro__.observe(element);
    31. }
    32. // 将监听事件方法添加到元素的__resizeListeners__字段下
    33. element.__resizeListeners__.push(fn);
    34. }
    35. // 删除监听方法
    36. /* istanbul ignore next */
    37. export function removeResizeListener(element: any, fn: () => any) {
    38. if (!element || !element.__resizeListeners__) return;
    39. element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
    40. if (!element.__resizeListeners__.length) {
    41. element.__ro__.disconnect();
    42. }
    43. }
    44. // 手动触发window的resize事件
    45. export function triggerWindowResize() {
    46. // 因为这个resize事件只有window的大小改变了才会触发,所以这里手动触发
    47. // 这个在折叠组件中有使用
    48. // 创建一个事件,参数表示事件类型
    49. const event = document.createEvent('HTMLEvents');
    50. // 定义事件名为'resize'.
    51. // 第二个参数:是Boolean决定该事件是否应该冒泡通过事件链与否。设置后,只读属性Event.bubbles 将提供其值。
    52. // 第三个参数:是Boolean定义该事件是否可以取消。设置后,只读属性Event.cancelable将提供其值。
    53. event.initEvent('resize', true, true);
    54. (event as any).eventType = 'message';
    55. // 让window触发这个事件
    56. window.dispatchEvent(event);
    57. }

    完善ts类型,移除注释

    1. import ResizeObserver from 'resize-observer-polyfill'
    2. // 自定义HTML元素
    3. type CustomizedHTMLElement<T> = HTMLElement & T
    4. export type ResizableElement = CustomizedHTMLElement<{
    5. __resizeListeners__: Array<(...args: unknown[]) => unknown>
    6. __ro__: ResizeObserver
    7. }>
    8. const resizeHandler = function (entries: ResizeObserverEntry[]) {
    9. for (const entry of entries) {
    10. const listeners =
    11. (entry.target as ResizableElement).__resizeListeners__ || []
    12. if (listeners.length) {
    13. listeners.forEach((fn) => {
    14. fn()
    15. })
    16. }
    17. }
    18. }
    19. export const addResizeListener = function (
    20. element: ResizableElement,
    21. fn: (...args: unknown[]) => unknown
    22. ): void {
    23. if (!element) return
    24. if (!element.__resizeListeners__) {
    25. element.__resizeListeners__ = []
    26. element.__ro__ = new ResizeObserver(resizeHandler)
    27. element.__ro__.observe(element)
    28. }
    29. element.__resizeListeners__.push(fn)
    30. }
    31. export const removeResizeListener = function (
    32. element: ResizableElement,
    33. fn: (...args: unknown[]) => unknown
    34. ): void {
    35. if (!element || !element.__resizeListeners__) return
    36. element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1)
    37. if (!element.__resizeListeners__.length) {
    38. element.__ro__.disconnect()
    39. }
    40. }