Как чередовать moveStart в Firefox? - PullRequest
       31

Как чередовать moveStart в Firefox?

2 голосов
/ 07 сентября 2010

Кто-нибудь знает, как использовать range.setStart так же, как range.moveStart работает в IE? Я хотел бы реализовать возврат / удаление в JS, что-то вроде этого:

range.moveStart (символ '', - 1); range.deleteContents ();

но в Firefox

Ответы [ 2 ]

1 голос
/ 07 сентября 2010

Firefox, наряду со всеми современными браузерами, кроме IE <= 8, использует <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html" rel="nofollow noreferrer"> DOM Ranges . Прямого аналога moveStart метода IE TextRange в IE нет, и в общем случае это сложно сделать. Если диапазон находится внутри текстового узла, а не в начале, это легко; в противном случае вам придется идти назад в документе, чтобы найти предыдущий текстовый узел и переместить диапазон в него. Следующее работает только в пределах одного текстового узла:

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 имеют метод модификации 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();
    }
}
0 голосов
/ 07 февраля 2019

Вот функция для расширения выделения, чтобы охватить полные слова:

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>
...