The new product manager wants to make a requirement to dynamically change the text content box and editor layout, which is the same as qq or wechat chat. In fact, I had no idea at first, but I finally fulfilled the requirement with the help of the omnipotent MDN and my wisdom. The core of the class is ResizeObserver, which is used for the first time, so some notes will be made here.

  • ResizeObserver met
  • ResizeObserver of actual combat

ResizeObserver met

  • The ResizeObserver Interface can report changes to the content or border box element, or to the box size of an SVG element.
  • ResizeObserver. Disconnect () the elimination of all observed target elements to observe an observer.
  • Resizeobserver.observe () Initializes observing a specified element.
  • Resizeobserver.observe () Unobserve a specified element.
  • New ResizeObserver(callback) Callback entries include Entries and observers.

Entries are an array consisting of all ResizeObserverEntry Objects. By for (Let Entry of Entries) {}, an entry represents a ResizeObserver object, and an entry consists of contentRect and Target.

In resize related practices, the entry contentRect object is the most important.

{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
Copy the code

ResizeObserver of actual combat

Make element resizable

  • The element applies the REsize CSS attribute.
  • Elements resizeobserverization.
<div class="main" :style="{minHeight: dynamicMainHeight}">
      <chatView></chatView>
</div>
Copy the code
.main {
    resize: vertical;
    overflow: auto;
}
Copy the code
 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 not supported'); }}},Copy the code

The editor component for dynamic calculation

<div
  class="rich-text-editor"
  contenteditable
  data-placeholder="Press Enter to send a message, Shift+Enter line feed."
  :style="{height: dynamicHeight}"
></div>
Copy the code
computed: {
  dynamicHeight() {
    return `${defaultEditorHeight + this.deltaHeight}px`; }},this.$bus.$on('rerenderViewAndEditor'.(deltaHeight) = > {
    this.deltaHeight = deltaHeight;
});
Copy the code

View components that compute dynamically

The chatView component that automatically jumps to the latest message needs to subtract deltaHeight to increase the height of scrollHeight.

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

scrollToBottom() {
  this.$nextTick(() = > {
    this.scrollTop = this.scrollHeight - this.deltaHeight;
  });
},
Copy the code

The final result

The resources

Developer.mozilla.org/en-US/docs/… Github.com/mdn/dom-exa…

Strive to be a good front end engineer!

I am looking forward to communicating with you and making progress together. Welcome to join the technical discussion group I created which is closely related to front-end development:

  • SegmentFault column: Be a good front-end engineer while you’re still young
  • Zhihu column: Be an excellent front-end engineer while you are still young
  • Github blog: Personal blog 233 while You’re Still Young
  • excellent_developers

Strive to be an excellent front-end engineer!