Вставить HTML после выделения

Я хочу иметь возможность дважды щелкнуть, чтобы выделить какой-то текст в элементе div, который затем запускает функцию JavaScript, которая вставляет некоторый HTML-код после выделенного текста, очень похоже на «edit / reply» функция в Google Wave.

Я уже установил, как вызывать функцию по двойному щелчку, она находит выбор и затем вставляет HTML после него, что является проблемой.

10
задан Lucy 30 August 2010 в 00:18
поделиться

3 ответа

Следующая функция вставит узел DOM (элемент или текстовый узел) в конце выбора во всех основных браузерах (обратите внимание, что Firefox теперь позволяет множественный выбор по умолчанию; в следующем используется только первый выбор):

function insertNodeAfterSelection(node) {
    var sel, range, html;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.collapse(false);
            range.insertNode(node);
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        range.collapse(false);
        html = (node.nodeType == 3) ? node.data : node.outerHTML;
        range.pasteHTML(html);
    }
}

Если вы предпочитаете вставлять строку HTML:

function insertHtmlAfterSelection(html) {
    var sel, range, node;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = window.getSelection().getRangeAt(0);
            range.collapse(false);

            // Range.createContextualFragment() would be useful here but is
            // non-standard and not supported in all browsers (IE9, for one)
            var el = document.createElement("div");
            el.innerHTML = html;
            var frag = document.createDocumentFragment(), node, lastNode;
            while ( (node = el.firstChild) ) {
                lastNode = frag.appendChild(node);
            }
            range.insertNode(frag);
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        range.collapse(false);
        range.pasteHTML(html);
    }
}

Обновление от 18 января 2012 г.

Наконец, вот версия, которая вставляет HTML и сохраняет выделение (т. е. расширяет выделение, чтобы включить исходное выбранное содержимое плюс вставленное содержимое).

Живая демонстрация: http://jsfiddle.net/timdown/ JPb75/1/

Код:

function insertHtmlAfterSelection(html) {
    var sel, range, expandedSelRange, node;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = window.getSelection().getRangeAt(0);
            expandedSelRange = range.cloneRange();
            range.collapse(false);

            // Range.createContextualFragment() would be useful here but is
            // non-standard and not supported in all browsers (IE9, for one)
            var el = document.createElement("div");
            el.innerHTML = html;
            var frag = document.createDocumentFragment(), node, lastNode;
            while ( (node = el.firstChild) ) {
                lastNode = frag.appendChild(node);
            }
            range.insertNode(frag);

            // Preserve the selection
            if (lastNode) {
                expandedSelRange.setEndAfter(lastNode);
                sel.removeAllRanges();
                sel.addRange(expandedSelRange);
            }
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        expandedSelRange = range.duplicate();
        range.collapse(false);
        range.pasteHTML(html);
        expandedSelRange.setEndPoint("EndToEnd", range);
        expandedSelRange.select();
    }
}
14
ответ дан 3 December 2019 в 22:34
поделиться

window.getSelection() предоставит вам выделенный текст (Документация). Вы можете использовать jQuery.after() (Документация), чтобы вставить новый html после элемента.

При вызове выбранной вами текстовой функции вам придется пройтись по всем элементам DOM, проверяя их позиции x и y до текущей позиции курсора — получить ближайший элемент и вставить после него или использовать функцию .elementFromPoint(x,y) (Документация)

Это лучший способ, который я могу сейчас придумать. Это не идеально, но с чего-то начать.

1
ответ дан 3 December 2019 в 22:34
поделиться

Не знаю, возможно ли это, но я думаю о частичном решении.

В событии двойного щелчка вы можете получить объект event и получить доступ к свойству target.

Имея целевой элемент, можно получить выделенный текст.

Теперь получите html целевого элемента и найдите индекс выделенного текста и его длину, вставьте свой html в позицию index + length.

Я думаю, вы уже видели проблему, она может совпадать с текстом в нескольких местах. Чтобы решить эту проблему, вам, возможно, придется найти положение курсора и сравнить его с элементом, я не знаю, как это сделать...

Надеюсь, я смог немного помочь.

0
ответ дан 3 December 2019 в 22:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: