admin管理员组

文章数量:1122832

Suppose I have a script that intends to implement “smart brackets” in <textarea> and <input> elements: whenever the user types in a bracket or quotation mark character while selection is non-empty, the selection is wrapped inside an appropriate matching pair of brackets or quotation marks. The text, with the inserted surrounding brackets, stays selected. It looks like this:

document.addEventListener('keydown', ev => {
  const input = ev.target.closest('input, textarea');
  if (!input)
    return;
  if (input.selectionStart === input.selectionEnd)
    return;

  const surround = (op, cl) => {
    ev.preventDefault();
    const i0 = input.selectionStart;
    const i1 = input.selectionEnd;
    input.focus();
    // execCommand preserves the undo stack, unlike assigning to .value
    document.execCommand(
      'insertText', false,
      `${op}${input.value.substring(i0, i1)}${cl}`);
    input.selectionStart = i0;
    input.selectionEnd = i1 + `${op}${cl}`.length;
  };

  switch (ev.key) {
  case '(':
    return surround('(', ')');
  case '[':
    return surround('[', ']');
  case '{':
    return surround('{', '}');
  case '"':
    return surround('"', '"');
  case "'":
    return surround("'", "'");
  }
}, false);
input, textarea { width: 100%; }
<textarea>select text and press an opening bracket…</textarea>

本文标签: