在选择之前和之后添加和删除字符

Append and remove characters before and after selection

如何获取 beforeafter selected 文本的字符,然后删除它们?或者更确切地说,如果 selected 文本在字符内,删除周围的字符,这样如果有任何额外的空格,字符仍将被删除。

例如,双击文本时,会select文本,而不是前后的反引号。然后我想删除那些反引号。

我有它可以向 selection 添加字符,但是当只 select 编辑文本而不是额外的字符时,我不知道如何删除它们。

$(document).on('click', 'button', function(e) {
  var target = $(this).attr('class');
  var str = window.getSelection();
  var text = str.toString().trim();
  var l = text.length;

  if ($(str.baseNode).closest('.input').length > 0) {
    switch (target) {
      case 'test':
        if ((text.charAt(0) != "`" && text.charAt(l - 1))) {
          var replacementText = "`" + text + "` ";
        } else {
          var rid = text.replace(/`/g, '');
          var replacementText = rid + ' ';
        }
        break;
    }
    formatSelection(str, text, replacementText);
  }
});

// format with buttons
function formatSelection(str, text, replacementText) {
  var sel, range;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.rangeCount) {
      range = sel.getRangeAt(0);
      range.deleteContents();
      range.insertNode(document.createTextNode(replacementText));
    }
  } else if (document.selection && document.selection.createRange) {
    range = document.selection.createRange();

    range.text = replacementText;
  }
}
.input {
  border: 1px solid #ccc;
  padding: 10px;
}

p {
  display: inline;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="test">format</button>

<div contenteditable="true" class="input">
  `text`
</div>

我会建议使用纯 JS 的不同方法,请参阅代码段中的评论:

var newText;
const elem = document.querySelector('.input');

document.querySelector('.test').addEventListener('click', e => {
  // get the content of the div
  const text = elem.innerHTML;

  // get the selection, in a string format, trim the white spaces
  const selection = window.getSelection();
  const selectionContent = selection.toString().trim();

  // if there's a word selected
  if (selectionContent) {
    const range = selection.getRangeAt(0)

    // selected line
    const line = range.startContainer.data;

    // indexes of the section
    const startIndex = range.startOffset;
    const endIndex = range.endOffset;

    // check if the backticks are included in the selection
    const backticksIncluded = selectionContent.match(/\`.*?\`/g) ? true : false;

    // check if the selected word is wrapped with backticks    
    const hasBackticks = backticksIncluded || "`" + selectionContent + "`" === line.slice(startIndex - 1, endIndex + 1);

    // check if the selection has a space in the end
    const space = selection.toString().endsWith(" ") ? " " : "";

    if (hasBackticks) {
      // if the selected text with backticks is found, 
      // replace it with the original selection ( without backticks)
      const startContent = line.slice(0, startIndex - (backticksIncluded ? 0 : 1));
      const endContent = line.slice(endIndex + (backticksIncluded ? 0 : 1));

      const newWord = backticksIncluded ? selectionContent.slice(1, -1) : selectionContent

      newText = startContent + newWord + space + endContent;
    } else {
      // if it doesn't have backticks, 
      // replace the selected text with the one having backticks
      const startContent = line.slice(0, startIndex);
      const endContent = line.slice(endIndex);

      newText = startContent + "`" + selectionContent + "`" + space + endContent;
    }

    // set the new content to the div
    elem.innerHTML = elem.innerHTML.replace(line.trim(), newText);
  }
});
<button class="test">format</button>

<div contenteditable="true" class="input">hello `text` hello world</div>