Requirement: Simulate wechat PC client chat window – send box, by dragging the upper edge of the send box, you can manually adjust the height. Think of the Element-UI table component, where columns can be dragged to change width.

1. Analysis of ideas

Element-ui idea: At the edge of the table and column, drag out a line (visible) that moves with the mouse. When the mouse is released, the line disappears and the column resets its width.

My idea: text box-upper edge, add a line (invisible), drag the mouse line, real-time change the text box-wrap box height, thus changing the height of the text box.

2. Precautions

  • Mouse events involved: Mousedown, Mousemove, mouseup.
  • In mouseDown, you need to disable the user from selecting text and dragging elements in the web page. Restore when mouseup.
  • Text box-Wrap = Text box + line. The height of the text box must be set to calc(100% – line height).

3. Code practice

<div id="app">
    <template>
      <h2>Drag the top edge of the DIV to change the height</h2>

      <! -- textbox wrap -->
      <div 
        ref="rTextareaWrap" 
        class="drag-textarea"
      >
        <! -- Guide line (used to adjust the height of text box) -->
        <div
          ref="rResizeLine"
          class="resize-line"
          @mousedown="handleMouseDown"
        ></div>

        <! -- Textbox -->
        <textarea></textarea>
      </div>
    </template>
  </div>
Copy the code
body {
  padding-top: 200px;
}
.drag-textarea {
  position: absolute;
  bottom: 200px;
  width: 300px;
  height: 250px;
}
.drag-textarea .resize-line {
  height: 5px;
  cursor: move;
}
.drag-textarea textarea {
  width:100%;
  /* Key attributes */
  height: calc(100% - 5px);
  padding: 0;
  border: 1px solid # 333;
  resize: none;
}
Copy the code
// enumeration - text box wrap Maximum/minimum height
const TextAreaWrap = {
  MaxHeight: 400.MinHeight: 150
};

new Vue({
  data () {
    return{}},methods: {
    /** * Handles mouse press events **@param {MouseEvent} Mouse events */
    handleMouseDown (event) {
      // Disables the user from selecting text in the web page
      document.onselectstart = () = > false;
      // Disallows the user from dragging elements
      document.ondragstart = () = > false;

      // Save the last mouse position (Y-axis)
      this.dragState = {
        // Where the mouse starts to move (Y-axis)
        'startMouseTop': event.clientY,
        // Last mouse position (Y-axis)
        'endMouseTop': event.clientY
      };

      // Bind mouse movement events
      document.addEventListener('mousemove'.this.handleMouseMove);
      // Bind the mouse release event
      document.addEventListener('mouseup'.this.handleMouseUp);
    },

    /** * Handles mouse movement events **@param {MouseEvent} Mouse events */
    handleMouseMove (event) {
      const { rTextareaWrap, rResizeLine } = this.$refs;
      // Get the last mouse position (Y-axis)
      const { endMouseTop } = this.dragState;
      // Get the current height of the text box
      const oldTextAreaHeight = rTextareaWrap.getBoundingClientRect().height;
      // The new height of the text box
      let newTextAreaHeight = 0;

      // Calculate the mouse movement distance
      const distance = Math.abs(
        parseInt(((endMouseTop - event.clientY) * 100).toString(), 10) / 100
      );

      // If the mouse moves up
      if (endMouseTop > event.clientY) {
        // The height of the sending box reaches the maximum
        if (oldTextAreaHeight >= TextAreaWrap.MaxHeight)
        {
          // Change the cursor to be moved down
          rResizeLine.style.cursor = 's-resize';
          return false;
        }

        // Calculates the new sender height
        newTextAreaHeight = oldTextAreaHeight + distance;
      }
      // If the mouse moves down
      else
      {
        // The height of the sending box reaches the minimum
        if (oldTextAreaHeight <= TextAreaWrap.MinHeight)
        {
          // Change the cursor to be moved up
          rResizeLine.style.cursor = 'n-resize';
          return false;
        }

        // Calculates the new sender height
        newTextAreaHeight = oldTextAreaHeight - distance;
      }

      // Compatible with fast mouse dragging: the height of the new sender box cannot exceed the maximum value
      if (newTextAreaHeight > TextAreaWrap.MaxHeight)
      {
        newTextAreaHeight = TextAreaWrap.MaxHeight;
      }

      // Compatible with fast mouse dragging: the new sender height cannot be smaller than the minimum value
      if (newTextAreaHeight < TextAreaWrap.MinHeight)
      {
        newTextAreaHeight = TextAreaWrap.MinHeight;
      }

      // Change the height of the sending box
      rTextareaWrap.style.height = newTextAreaHeight + 'px';
      // Change the cursor to moveable
      rResizeLine.style.cursor = 'move';

      // Update the last mouse position (Y-axis)
      this.dragState.endMouseTop = event.clientY;
    },

    /** * Handle the mouse release event */
    handleMouseUp () {
      // Remove the mouse movement event
      document.removeEventListener('mousemove'.this.handleMouseMove);
      // Remove the mouse release event
      document.removeEventListener('mouseup'.this.handleMouseUp);
      // Allow the user to select text in the web page
      document.onselectstart = null;
      // Allow the user to drag elements
      document.ondragstart = null;
    }
  }
}).$mount('#app')
Copy the code