如何在 Firefox 中替代 moveStart?

发布于 2024-09-18 04:58:53 字数 164 浏览 6 评论 0原文

有谁知道如何使用 range.setStart 与 range.moveStart 在 IE 中的工作方式相同?我想在 JS 中实现退格/删除,如下所示:

range.moveStart('character',-1); 范围.deleteContents();

但在火狐浏览器中

Does anybody know how to use range.setStart in the same way as range.moveStart works in IE? I'd like to implement backspace/delete in JS, something like this:

range.moveStart('character',-1);
range.deleteContents();

but in Firefox

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

︶ ̄淡然 2024-09-25 04:58:53

Firefox 以及除 IE <= 8 之外的所有现代浏览器都使用 DOM 范围。没有与 IE 的 TextRangemoveStart 方法直接类似的方法,并且在一般情况下执行起来很棘手。如果范围在文本节点内而不是在开始处,那就很容易;否则,您需要在文档中向后移动以找到前面的文本节点并将范围移入其中。以下仅适用于单个文本节点:

function backspace() {
    var sel = window.getSelection();

    // If there is a selection rather than a caret, just delete the selection
    if (!sel.isCollapsed) {
        sel.deleteFromDocument();
    } else if (sel.rangeCount) {
        var range = sel.getRangeAt(0);
        if (range.startContainer.nodeType == 3 && range.startOffset > 0) {
            range.setStart(range.startContainer, range.startOffset - 1);
            sel.removeAllRanges();
            sel.addRange(range);
            sel.deleteFromDocument();
        }
    }
}

WebKit 和 Firefox 4 具有 modify 方法 < code>Selection 对象 完全解决了问题:

function backspace2() {
    var sel = window.getSelection();

    // If there is a selection rather than a caret, just delete the selection
    if (!sel.isCollapsed) {
        sel.deleteFromDocument();
    } else if (sel.rangeCount && sel.modify) {
        sel.modify("extend", "backward", "character");
        sel.deleteFromDocument();
    }
}

Firefox, along with all modern browsers except IE <= 8 uses DOM Ranges. There's no direct analogue to the moveStart method of IE's TextRange and it's tricky to do in the general case. If the range is within a text node and not at the start, it's easy; otherwise you'll need to walk backwards in the document to find the preceding text node and move the range into it. The following only works within a single text node:

function backspace() {
    var sel = window.getSelection();

    // If there is a selection rather than a caret, just delete the selection
    if (!sel.isCollapsed) {
        sel.deleteFromDocument();
    } else if (sel.rangeCount) {
        var range = sel.getRangeAt(0);
        if (range.startContainer.nodeType == 3 && range.startOffset > 0) {
            range.setStart(range.startContainer, range.startOffset - 1);
            sel.removeAllRanges();
            sel.addRange(range);
            sel.deleteFromDocument();
        }
    }
}

WebKit and Firefox 4 have the modify method of Selection objects which solves the problem completely:

function backspace2() {
    var sel = window.getSelection();

    // If there is a selection rather than a caret, just delete the selection
    if (!sel.isCollapsed) {
        sel.deleteFromDocument();
    } else if (sel.rangeCount && sel.modify) {
        sel.modify("extend", "backward", "character");
        sel.deleteFromDocument();
    }
}
停滞 2024-09-25 04:58:53

这是一个扩展选择以覆盖完整单词的函数:

document.body.addEventListener('keydown', ({key}) => {
    if (key === 'Enter') {
        getWordRange();
    }
});

function getWordRange() {
    const range = document.getSelection().getRangeAt(0);
    const {startContainer, startOffset, endContainer, endOffset} = range;
    const treeWalker = document.createTreeWalker(
        document.body,
        NodeFilter.SHOW_TEXT,
    );

    treeWalker.currentNode = startContainer;

    do {
        const container = treeWalker.currentNode;
        const content = container === startContainer
            ? container.textContent.substr(0, startOffset)
            : container.textContent;
        const offset = content.lastIndexOf(' ') + 1;

        range.setStart(container, 0);

        if (offset) {
            range.setStart(container, offset);
            break;
        }
    } while (treeWalker.previousNode());

    treeWalker.currentNode = endContainer;

    do {
        const container = treeWalker.currentNode;
        const content = container === endContainer
            ? container.textContent.substr(endOffset)
            : container.textContent;
        const offset = content.indexOf(' ');
        const actualOffset = offset + container.textContent.length - content.length;

        range.setEnd(container, content.length);

        if (offset !== -1) {
            range.setEnd(container, actualOffset);
            break;
        }
    } while (treeWalker.nextNode());
}
<p>
  Select text then hit Enter to expand selection to word edges.<br>
  Works with <b>nested <i>tags</i></b> as well.
</p>

Here’s a function to expand selection to cover full words:

document.body.addEventListener('keydown', ({key}) => {
    if (key === 'Enter') {
        getWordRange();
    }
});

function getWordRange() {
    const range = document.getSelection().getRangeAt(0);
    const {startContainer, startOffset, endContainer, endOffset} = range;
    const treeWalker = document.createTreeWalker(
        document.body,
        NodeFilter.SHOW_TEXT,
    );

    treeWalker.currentNode = startContainer;

    do {
        const container = treeWalker.currentNode;
        const content = container === startContainer
            ? container.textContent.substr(0, startOffset)
            : container.textContent;
        const offset = content.lastIndexOf(' ') + 1;

        range.setStart(container, 0);

        if (offset) {
            range.setStart(container, offset);
            break;
        }
    } while (treeWalker.previousNode());

    treeWalker.currentNode = endContainer;

    do {
        const container = treeWalker.currentNode;
        const content = container === endContainer
            ? container.textContent.substr(endOffset)
            : container.textContent;
        const offset = content.indexOf(' ');
        const actualOffset = offset + container.textContent.length - content.length;

        range.setEnd(container, content.length);

        if (offset !== -1) {
            range.setEnd(container, actualOffset);
            break;
        }
    } while (treeWalker.nextNode());
}
<p>
  Select text then hit Enter to expand selection to word edges.<br>
  Works with <b>nested <i>tags</i></b> as well.
</p>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文