问题
How can I get the characters before AND after the selected text, and then remove them? Or rather, if the selected text is within the characters, remove the surrounding characters, that way if there are any extra spaces the characters will still be removed.
For example, when double clicking on the text, it will select the text, but not the backticks before and after. I want to then remove those backticks.
I have it where I can add characters to the selection, but when only selecting the text and not the extra characters, I do not know how to remove them.
$(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>
回答1:
I would suggest a different approach, using plain JS, see the comments in the snippet :
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>
来源:https://stackoverflow.com/questions/57581621/append-and-remove-characters-before-and-after-selection