<pre> внутри редактируемого содержимого, замените <br>на \ r \ n - PullRequest
0 голосов
/ 27 июля 2011

У меня есть контент редактируемый div. В этом я вставляю тег some code. Этот тег предназначен для того, чтобы пользователь мог вводить отформатированный код, аналогично SO.

Проблема, с которой я столкнулся, заключается в том, что FF вставляет теги <br> вместо \ r \ n, что в обычном HTML-коде будет правильным, но в действительности я действительно хочу \ r \ n.

Я пытался прикрепить делегата к родителю. Но это не срабатывает для вложенных элементов dom. Итак

$('#contenteditablediv').delegate('pre', 'keyup', function() { ... });

Не стреляет. Я также попытался обработать обычный keyup на родительском div и заменить все brs в pre тегах на \ r \ n. Но это портит карету и неуклюже.

Есть ли предпочтительный способ сделать это?

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

Большое спасибо

Ответы [ 2 ]

4 голосов
/ 27 июля 2011

Я действительно нашел решение.Это не идеально, и я рассматриваю возможность интегрировать codemirror , как предложено Mrchief.Единственная проблема заключается в том, что мое текущее решение позволяет мне редактировать разметку, которая будет сохранена в серверной части и отображена позже.Это действительно WYSIWYG.Я должен отметить, что мой редактор является частью большей contenteditable статьи, в которой я хочу, чтобы добавить некоторые фрагменты кода.

1004 * Используя редактор, как CodeMirror было бы удивительным, но Id должны лишить его перед сохранением и мойблоки кода должны отображаться в виде текстовой области (а не в виде RSS, как раньше).

В любом случае, для всех, кто интересуется здесь, есть мое решение / хак.вложенные теги <pre> и т. д. в contenteditables, если они заключены в элемент с contenteditable="false".Поэтому вместо вставки:

<pre>some code</pre

я вставил:

<code contenteditable="false"><pre>code snippet here</pre>

Затем я добавил делегата следующим образом.

var getFirstRange = function() {
    var sel = rangy.getSelection();
    return sel.rangeCount ? sel.getRangeAt(0) : null;
}

contenteditablediv
    .delegate('pre', 'keydown', function(event) { 
        switch(event.keyCode) {
            case 13:
                var range = getFirstRange(), 
                    added = false,
                    newline = document.createTextNode('\r\n');

                if (range) {
                    range.insertNode(newline);              
                    range.setEndAfter(newline);
                    range.setStartAfter(newline);
                    var sel = rangy.getSelection();
                    sel.setSingleRange(range)
                    added = true;
                } 

                if (added) {
                    event.preventDefault();
                }
                break;
            case 9:
                // insert a tab
                var range = getFirstRange(),
                    tab = document.createTextNode('\t');
                if (range) {
                    range.insertNode(tab);
                    var sel = rangy.getSelection();
                    range.setEndAfter(tab);
                    range.setStartAfter(tab);
                    sel.setSingleRange(range)
                } 
                return false;   
        }
    }).delegate('pre', 'click', function() { 
        $(this).attr('contenteditable', true);
    }).delegate('pre', 'blur', function() {
        $(this).removeAttr('contenteditable');
    });

Это событие происходит.Я добавил удаление клика / размытия, чтобы переключить contenteditable на внутреннем предварительном теге, чтобы после этого это не сохранялось, но это можно сделать на стороне сервера.Это позволяет мне вставлять символы \ t в клавишу табуляции и \ r \ n вместо br.

1 голос
/ 27 июля 2011

Простой ответ: Сделайте это на стороне сервера. Все внутри contentEditable div это просто текст. Следовательно, ваш delegate никогда не будет стрелять.

Я бы также предложил посмотреть на плагин codemirror , который уже может обрабатывать все это.

...