我试图从用户选择的文本中删除前导或尾随(有时是两个)空格。根据此answer实施。这适用于简单的情况,但是,当所选文本包含标签或
时,它会失败。
示例:在fiddle尝试从右到左突出显示-- hi this is bob.
,包括最后的空格,然后按修剪。
这导致:
Uncaught IndexSizeError: Failed to execute 'setEnd' on 'Range': The offset 24 is larger than or equal to the node's length (5).
我想这可以用
抓住 if (method == range.setEnd && range.startOffset + ind >= range.endContainer.length)
但我不确定如何处理它。 我还尝试使用
替换硬空间e2 = document.getElementById('e2');
e2.innerHTML = e2.innerHTML.replace(/ /gi, ' ');
但是,这会使选择为空。 代码:
function removeWsFromSelection(fromStart) {
selection = window.getSelection();
range = selection.getRangeAt(0);
if (fromStart) {
regex = /[^\s]/;
container = range.startContainer;
method = range.setStart;
} else {
regex = /\s+$/;
container = range.endContainer;
method = range.setEnd;
}
match = regex.exec(selection.toString());
if (match) {
ind = match.index;
if (ind > 0) {
// ind is the first non-ws char from the start or first ws char from the end,
// hence (startOffset + ind)
method.call(range, container, range.startOffset + ind);
rng = range.cloneRange();
selection.removeAllRanges();
selection.addRange(rng);
}
}
}
不幸的是,顺便说一句,Selection.modify
对我来说并不起作用,而且它被认为是non-standard。
答案 0 :(得分:1)
如果你对范围修改没问题,你可以从开始和结束检查修剪符号的长度,然后修改范围的 startOffset 和 endOffset。但是对于 startContainer 和 endContainer 不是同一个节点的情况,这肯定不是灵丹妙药。至少它适用于某些情况。
const sel = window.getSelection();
const text = sel.toString();
const range = sel.getRangeAt(0);
const startOffset = text.length - text.trimStart().length;
const endOffset = text.length - text.trimEnd().length;
if (startOffset) {
range.setStart(range.startContainer, range.startOffset + startOffset);
}
if (endOffset) {
range.setEnd(range.endContainer, range.endOffset - endOffset);
}
答案 1 :(得分:0)
这非常难看并且不处理一般情况,但似乎有效:
function removeWsFromSelection(fromStart) {
selection = window.getSelection();
range = selection.getRangeAt(0);
if (fromStart) {
regex = /[^\s]/;
container = range.startContainer;
method = range.setStart;
}
else {
regex = /\s+$/;
container = range.endContainer;
method = range.setEnd;
}
match = regex.exec(selection.toString());
if (match) {
ind = match.index;
if (ind > 0) {
// ind is the first non-ws char from the start or first ws char from the end,
// hence (startOffset + ind)
if (method == range.setEnd && range.startOffset + ind >= range.endContainer.length) {
match = regex.exec(range.endContainer.textContent);
if (match) {
range.setEnd(range.endContainer, match.index);
}
}
else {
method.call(range, container, range.startOffset + ind);
}
rng = range.cloneRange();
selection.removeAllRanges();
selection.addRange(rng);
}
}
}