Как заменить выделенный текст на html в элементе contenteditable?

С элементом contenteditable, как я могу заменить выбранный контент своим собственным html?


person Frodik    schedule 06.06.2011    source источник
comment
На вторую часть этого вопроса («заменить выделенный текст моим собственным html») нет ответа в вопросе, указанном как ссылка на этот вопрос, являющийся дубликатом.   -  person Brian M. Hunt    schedule 16.07.2014
comment
Я удалил уже отвеченную часть, чтобы соответствовать правилу «один вопрос на вопрос».   -  person Brigand    schedule 16.07.2014
comment
Связано - stackoverflow.com/q/3997659/104380   -  person vsync    schedule 20.09.2020


Ответы (2)


См. рабочий jsFiddle здесь: http://jsfiddle.net/dKaJ3/2/< /сильный>

function getSelectionHtml() {
    var html = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            html = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            html = document.selection.createRange().htmlText;
        }
    }
    alert(html);
}

Код взят из Tim Down: Вернуть HTML из выбранного пользователем текста

person NakedBrunch    schedule 06.06.2011
comment
Кстати, никогда не вызывайте функцию getSelection(), так как это переопределит значение по умолчанию и вызовет рекурсию стека. - person tetris11; 06.01.2013
comment
работает отлично! благодаря. как мне теперь заменить выделенный текст чем-то другим в той же позиции, что и текст? - person Varun; 10.04.2013
comment
неважно, нашел ответ: stackoverflow.com/questions/3997659/ - person Varun; 10.04.2013
comment
Хорошо, но еще один вопрос, пожалуйста, он возвращает выделенный текст из всего документа, как получить только выбранный div. Может быть div с отдельным классом? - person Pritom; 24.06.2013
comment
Это не решает проблему: как бы вы заменили выделение, если есть хотя бы две похожие строки? - person k102; 23.03.2016

Чтобы получить выбранный HTML, вы можете использовать функцию, которую я написал для этого вопроса. . Чтобы заменить выделение своим собственным HTML, вы можете использовать эта функция. Вот версия функции замены, которая вставляет строку HTML вместо узла DOM:

function replaceSelectionWithHtml(html) {
    var range;
    if (window.getSelection && window.getSelection().getRangeAt) {
        range = window.getSelection().getRangeAt(0);
        range.deleteContents();
        var div = document.createElement("div");
        div.innerHTML = html;
        var frag = document.createDocumentFragment(), child;
        while ( (child = div.firstChild) ) {
            frag.appendChild(child);
        }
        range.insertNode(frag);
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        range.pasteHTML(html);
    }
}

replaceSelectionWithHtml("<b>REPLACEMENT HTML</b>");
person Tim Down    schedule 06.06.2011
comment
Пожалуйста, определите node. Я думаю, мы можем просто удалить эту строку html = (node.nodeType == 3) ? node.data : node.outerHTML; - person H Dog; 25.06.2014
comment
@HDog: Да, ты прав. Похоже на скопированную строку, которую я забыл удалить. Я удалил это сейчас. Спасибо. - person Tim Down; 25.06.2014
comment
Почему «html» является как параметром функции, так и объявлением локальной переменной? Это работает благодаря stackoverflow.com/a/27963351/578812, но на первый взгляд это кажется запутанным. - person Craig A; 27.07.2016
comment
@CraigA: это ошибка. Я подозреваю, что скопировал и адаптировал функцию, у которой не было параметра html. Спасибо, что указали на это. - person Tim Down; 28.07.2016
comment
Замечательный ответ! Но есть одна вещь, которую я не понимаю, почему этот допустимый синтаксис: var frag = document.createDocumentFragment(), child; . Почему запятая не вызывает ошибку? Я был бы очень признателен, если бы вы могли объяснить, как работает это утверждение. - person flen; 28.02.2017
comment
@flen: оператор var в JavaScript позволяет объявлять несколько переменных в одном операторе, разделенных запятой, при этом каждая переменная может иметь начальное значение. Подробнее на MDN - person Tim Down; 28.02.2017
comment
@TimDown Большое спасибо! Теперь я понял, child - это просто объявление переменной без какого-либо присвоения. Так же, как var frag = 42; var child; - person flen; 01.03.2017
comment
@TimDown, я использовал это в div ContentEditable. Но кажется, что вы можете отменить/повторить что-либо, вставленное с помощью этого фрагмента. Есть ли способ сделать это так, чтобы отменить/повторить его? Спасибо - person Xahed Kamal; 27.03.2018
comment
@XahedKamal: я так не думаю. Я считаю, что изменения, сделанные с помощью document.execCommand(), переходят стек отмены действий браузера, но нет команды, которая дает вам точный контроль над тем, какой HTML-код вставляется и как он вставляется. - person Tim Down; 28.03.2018