从js中的窗口选择中删除空格

时间:2016-05-04 10:45:03

标签: javascript html

我试图从用户选择的文本中删除前导或尾随(有时是两个)空格。根据此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

2 个答案:

答案 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);
        }
      }
    }