Read the full article and you will get the following solutions.

  1. Click on the long text to edittextareaAutomatically gain focus
  2. Automatically scale the height with the input value
  3. Add information that can be copied
  4. Pastable text
  5. Pastable picture

The following example code executes on Chrome80

Plan a

HTML 5 Textarea element

1. Automatically get focus

Click Edit to get the focus automatically and the cursor jumps to the front.

**selectionEnd and selectionStart** are used to represent the start and end positions of selected text. The DOM interface instance is HTMLTextAreaElement. The setSelectionRange method is used to select the text in the input box. TextAreaElement.setSelectionRange(selectionStart, selectionEnd, [optional] selectionDirection);

So we just do selectionStart === selectionEnd === value.length, and then the cursor is at the end.

edit.addEventListener("click".function() {
  txt.classList.add("hidden");
  document.body.insertBefore(textarea, edit);
  textarea.innerHTML = "This is information that needs to be edited.";
  textarea.focus();
  // textarea.selectionEnd = textarea.innerHTML.length;

  textarea.setSelectionRange(
    textarea.innerHTML.length,
    textarea.innerHTML.length
  );
});
Copy the code

2. Adaptive height

If the height is not set, the newline will have a scrollbar, so if the textarea scrollbar disappears and its height = scrollHieght, then the input event will be required to monitor the textarea change. Make the textarea height dynamically equal to its scrollHeight:

textarea.addEventListener("input".function() {
	this.style.height = `The ${this.scrollHeight}px`;
});
Copy the code

Why does every input increase the height (4px each time)? Safari has the same effect after testing, Firefox is as expected and the height does not increase. Check Chrome console and find that textarea has many built-in styles. Can now be highly adaptive as content increases normally.

<style>
textarea {
  padding: 0;
}
</style>
<textarea></textarea>
<script>
const textarea = document.createElement("textarea");
textarea.addEventListener("input".function(e) {
  this.style.height = `The ${this.scrollHeight}px`;
});
</script>
Copy the code

Why does the padding not increase the height when you type in the padding value? (No reasonable explanation is found, welcome to leave a message to discuss and answer)

The scrollHeight is a read-only property (MDN- document). The scrollHeight is recalculated. Only change the height, then:

textarea.addEventListener("input".function(e) {
  this.style.height = "inherit";
  this.style.height = `The ${this.scrollHeight}px`;
});
Copy the code

I’m up here and I’m done with adaptive input, but every time I flash a line, I’m gonna go one wave,

textarea {
  overflow: hidden;  // 防止换行出现滚动条闪动
  padding: 5px 10px;
  box-sizing: border-box;
  transition: all 0.2s linear;
}
Copy the code

If you set height to auto or inherit, the animation will not work. So the compromise is to reset the height when you delete it. You don’t need to reset the height when you type it. Delete without animation, temporarily did not think of a better way.

textarea.addEventListener("keyup".function(e) {
  if (e.keyCode === 8) {
    this.style.height = "inherit";
    this.style.height = `The ${this.scrollHeight}px`;
  } else {
    this.style.height = `The ${this.scrollHeight}px`; }});Copy the code

3. Support pasting text and pictures

Textarea can only enter text, not paste images.

textarea.addEventListener(
  "paste".function(e) {
    e.preventDefault();
    console.log(
      "paste",
      e.clipboardData.items,
      e.clipboardData.types,
      e.clipboardData.getData("text/html"),
      e.clipboardData.getData("text/plain"),
      e.clipboardData.getData("text/Files")); },false
);
Copy the code

Scheme 2

Div contenteditable replaces Textarea

1. Automatically get focus

Edit div Contenteditable to true, and use Range and Selection to move the cursor to the final effect.

edit.addEventListener("click", () => {
  textarea.setAttribute("contenteditable".true);
  textarea.focus();
  const range = document.createRange();

  // range contains the contents
  range.selectNodeContents(textarea);

  // range.setStart(textarea.firstChild, 0);
  // range.setStart(textarea.lastChild, textarea.innerHTML.length);

  // The starting position is the same
  range.collapse(false);
  const sel = window.getSelection();
  
  // Remove all fields from the selection.
  sel.removeAllRanges();
  
  // A Range object is added to the selection.
  sel.addRange(range);
});
Copy the code

2. Adaptive height

Div Contenteditable natural support comes from adaptive height based on input.

3. Paste pictures, text, etc

textarea.addEventListener("paste".function(e) {
  e.preventDefault();
  const clipboardData = e.clipboardData || e.originalEvent.clipboardData;
  // Get plain text
  let text = clipboardData.getData("text/plain");
  let file = clipboardData.getData("text/plain");
  // console.log(clipboardData.items, clipboardData.getData("text/Files"));

  // Insert img to do some uploading operations
  insertImg(clipboardData);

  // Enter only plain text
  document.execCommand("insertText".false, text);
});
Copy the code

This method can limit uploads to text or images only.

Feel free to comment on other highly adaptive textaREA solutions.