乐趣区

ResizeObserver是什么

新来的产品经理,想做一个和 qq 或者微信聊天一样的,上下拖动动态改变文本内容框和编辑器布局的需求。

其实一开始是一头雾水的,但是通过万能的 mdn,以及充满智慧的我,最终还是完成了这个需求。
其中最核心的还是 ResizeObserver 这个第一次用的类,所以会在这里做一些记录。

  • ResizeObserver 初识
  • ResizeObserver 实战

ResizeObserver 初识

  • ResizeObserver interface 可以报告元素 content 或者 border box,或者 svg 元素 box大小的变化
  • ResizeObserver.disconnect() 取消观察某个 observer 的所有 observed 目标元素。
  • ResizeObserver.observe() 初始化观察一个指定元素。
  • ResizeObserver.observe() 取消观察一个指定元素。
  • new ResizeObserver(callback) callback 的入参包括 entries 和 observer。

entries 是一个数组,它由所有的 ResizeObserverEntry object 组成。通过 for (let entry of entries) {} 的方式,entry 代表一个 ResizeObserver object,一个 entry 由 contentRect 和 target 组成。

在 resize 相关实践中,entry 的 contentRect 对象是最最重要的。

{target: div, contentRect: DOMRectReadOnly}
contentRect: DOMRectReadOnly
bottom: 312.3125
height: 292.3125
left: 20
right: 626
top: 20
width: 606
x: 20
y: 20
__proto__: DOMRectReadOnly
target: div
__proto__: ResizeObserverEntry

ResizeObserver 实战

Make element resizable

  • 元素应用 resize css 属性。
  • 元素 ResizeObserver 化。
<div class="main" :style="{minHeight: dynamicMainHeight}">
      <chatView></chatView>
</div>
.main {
    resize: vertical;
    overflow: auto;
}
 observeChatView() {if (window.ResizeObserver) {const viewElem = document.querySelector('.main');
      const resizeObserver = new ResizeObserver((entries) => {for (const entry of entries) {if (!this.initialHeight) {this.initialHeight = entry.contentRect.height;}
          if (this.initialHeight) {
            const deltaHeight = this.initialHeight - entry.contentRect.height;
            this.$bus.$emit('rerenderViewAndEditor', deltaHeight);
          }
        }
      });
      resizeObserver.observe(viewElem);
    } else {this.$Message.warning('不支持 ResizeObserver');
    }
  },
},

因为 resizable 组件动态渲染的组件

<div
  class="rich-text-editor"
  contenteditable
  data-placeholder="按下 Enter 发送消息,按下 Shift+Enter 换行"
  :style="{height: dynamicHeight}"
></div>
computed: {dynamicHeight() {return `${defaultEditorHeight + this.deltaHeight}px`;
  },
},
this.$bus.$on('rerenderViewAndEditor', (deltaHeight) => {this.deltaHeight = deltaHeight;});

最终效果

参考资料

https://developer.mozilla.org…
https://github.com/mdn/dom-ex…

努力成为优秀的前端工程师!

退出移动版