ResizeObserver是什麼?

qqResize.gif

新來的產品經理,想作一個和qq或者微信聊天同樣的,上下拖動動態改變文本內容框和編輯器佈局的需求。 其實一開始是一頭霧水的,可是經過萬能的mdn,以及充滿智慧的我,最終仍是完成了這個需求。 其中最核心的仍是ResizeObserver這個第一次用的類,因此會在這裏作一些記錄。css

  • 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組成。html

在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');
    }
  },
},
複製代碼

動態計算的editor組件

<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;
});
複製代碼

動態計算的view組件

自動跳到最新一條消息的chatView組件須要減去deltaHeight,從而增大scrollHeight的高度。git

this.$bus.$on('rerenderViewAndEditor', (deltaHeight) => {
  this.visiableHeight = document.body.clientHeight - deltaHeight;
  this.deltaHeight = deltaHeight;
});

scrollToBottom() {
  this.$nextTick(() => {
    this.scrollTop = this.scrollHeight - this.deltaHeight;
  });
},
複製代碼

最終效果

ResizeObserver.gif

參考資料

developer.mozilla.org/en-US/docs/… github.com/mdn/dom-exa…github

努力成爲優秀的前端工程師!數組

相關文章
相關標籤/搜索