其实一开始是一头雾水的,但是通过万能的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'); } }, },
动态计算的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的高度。
this.$bus.$on('rerenderViewAndEditor', (deltaHeight) => { this.visiableHeight = document.body.clientHeight - deltaHeight; this.deltaHeight = deltaHeight; }); scrollToBottom() { this.$nextTick(() => { this.scrollTop = this.scrollHeight - this.deltaHeight; }); },
最终效果
参考资料
https://developer.mozilla.org...
https://github.com/mdn/dom-ex...