Функция пользовательской кнопки jQuery Summernote

У меня здесь jsFiddle → http://jsfiddle.net/cm910t89/2/

Я создал пользовательскую кнопку в Summernote WYSIWYG Editor, и я не могу заставить свою функцию нормально работать внутри плагина.

Я хочу, чтобы пользователь мог выделить (или выбрать с помощью своего курсора) любой текст в редакторе, а затем щелкнуть по моей пользовательской кнопке, которая будет обертывать выделенный текст в теге span специальным классом 'snote',

Сейчас я могу обернуть выбранный в теге span этот класс, но все форматирование в редакторе стирается.

Может ли кто-нибудь помочь, чтобы выделенный текст был обернут в тег span, и форматирование остается тем же?

jsFiddle → http://jsfiddle.net/cm910t89/2/

$(document).ready(function() {
var editor = $('#summernote');
editor.summernote({
    height: ($(window).height() - 250),
    focus: false,
    toolbar: [
            ['style', ['bold', 'italic', 'underline', 'clear']],
            ['font', ['strikethrough']],
            ['fontsize', ['fontsize']],
            ['para', ['ul', 'ol', 'paragraph']],
            ['height', ['height']],
            ['view', ['fullscreen', 'codeview']],
        ],
    oninit: function() {
        // Add "open" - "save" buttons
        var noteBtn = '<button id="makeSnote" type="button" class="btn btn-default btn-sm btn-small" title="Identify a music note" data-event="something" tabindex="-1"><i class="fa fa-music"></i></button>';            
        var fileGroup = '<div class="note-file btn-group">' + noteBtn + '</div>';
        $(fileGroup).appendTo($('.note-toolbar'));
        // Button tooltips
        $('#makeSnote').tooltip({container: 'body', placement: 'bottom'});
        // Button events
        $('#makeSnote').click(function(event) {
            var highlight = window.getSelection(),  
            spn = '<span class="snote" style="color:blue;">' + highlight + '</span>',
            text = $('.note-editable').children('p').text(),
            range = highlight.getRangeAt(0),
            startText = text.substring(0, range.startOffset), 
            endText = text.substring(range.endOffset, text.length);

            $('.note-editable').html(startText + spn + endText);
        });
     },

});

Ответ 1

Так как $('.note-editable') является текстовым полем, когда вы вызываете .text(), он получает только текст для элемента, теряя весь html, добавляемый для добавления комментария, который будет отображаться для вас.

Вам не нужен весь этот код для замены выделенного текста. На самом деле все, что вам нужно, это созданный вами объект range! С ним вы вызываете .deleteContents(), чтобы очистить выбранный диапазон, а затем вызовите .insertNode(node), чтобы вставить динамически созданный диапазон с текстом:

$('#makeSnote').click(function(event) {
     var highlight = window.getSelection(),  
         spn = document.createElement('span'),
         range = highlight.getRangeAt(0)

     spn.innerHTML = highlight;
     spn.className = 'snote';  
     spn.style.color = 'blue';

     range.deleteContents();
     range.insertNode(spn);
});

Здесь работает fiddle.

Ответ 2

Попробуйте это

$('#makeSnote').click(function(event) {
    var highlight = window.getSelection(),  
    spn = '<span class="snote" style="color:blue;">' + highlight + '</span>',
    text = $(highlight.anchorNode).text(),
    range = highlight.getRangeAt(0),
    startText = text.substring(0, range.startOffset), 
    endText = text.substring(range.endOffset, text.length);
    $(highlight.anchorNode).replaceWith(startText + spn + endText);
});

Вместо этого я использовал anchorNode, потому что у вас есть другой HTML Node, кроме текста в TextArea.

Ответ 3

Я не использовал SummerNote, но, глядя на скрипты, это конвертер конвертирования textarea в контентный div. Поскольку это div, интервал сохраняется с тегами <p> и <br>, поэтому для сохранения форматирования вам просто нужно получить innerHTML, а не Text. Ответ от + Denis Ali должен работать, поскольку он оставляет теги точно там, где они есть, и только удаляет/повторно выводит выбранную часть.

Вы можете использовать innerHTML (JS) или $().html() (Jq), чтобы получить форматированное содержимое вместо .text, но если ни + Denis или это не работает, должно быть что-то другое, имеющее влияние. Денис должен был работать на основе вашей скрипки и библиотек.