Подтвердить что ты не робот

HTML-контент, доступный с нередактируемыми островами

У меня есть редактор WYSIWYG на основе браузера, где пользователи могут редактировать документы-шаблоны.

Документ-шаблон - это обычный html с некоторыми специальными "заполнителями кода слияния". Такой шаблон получает "экземпляр", заменяя эти заполнители данными, поступающими из БД. Это дает окончательный документ - экземпляр шаблона.

Мой текущий подход выглядит следующим образом:

<div contenteditable>
  Sample template with <input type=button class="mergecode" value="MergeCode1">.
</div>

(Онлайн-образец для игры: http://jsfiddle.net/tFBKN/)

В этом случае вход не редактируется и ведет себя как сплошной блок - именно то, что мне нужно. Пользователи могут удалять такие коды слияния, нажав DEL или BACKSPACE, как любые другие символы и т.д. Имея надлежащий CSS для такого ввода .mergecode, я могу добиться желаемого внешнего вида.

Но при таком подходе у меня три разные проблемы в трех разных UA:

  • IE - CSS { font:inherit } просто не работает, поэтому, если вход внутри <b>, как здесь, <b><input value="test"></b>, он не наследует стилей шрифта.
  • FF - Копия фрагмента, содержащего элемент <input>, удаляет этот вход из содержимого буфера обмена, поэтому дополнительная операция вставки вставляет все, кроме входных данных.
  • GC - нажмите {BACKSPACE} сразу после того, как <input> произведет странные результаты (bug)

Итак, я ищу другие идеи о том, как представлять не редактируемые встроенные блоки как "острова" в HTML.

Другой подход, который я пробовал до сих пор:

  • <span contenteditable="false">MergeCode1</span> - он не работает, так как большинство UA удаляют из node. Поэтому нельзя, скажем, применить <b> или <i> к вершине выделения, содержащего такой диапазон.

Любые другие идеи?

4b9b3361

Ответ 1

Еще одна идея, которая выглядит многообещающе:

Чтобы использовать пустой диапазон с ::before { content:"caption"; }, который должен создать не редактируемый блок, представленный в DOM, как node, в котором нет позиций каретки.

Вы можете попробовать его здесь http://jsfiddle.net/TwVzt/1/

Но этот подход не свободен от проблем (в моем случае): нет способа объявить ::before inline с помощью атрибута стиля DOM, и поэтому весь набор должен быть объявлен в CSS upfront. Но набор кодов слияния, который у меня есть, довольно большой, даже неизвестный заранее в некоторых случаях. Вздох.

Тем не менее, поставив этот рецепт здесь, если у кого-то будут лучшие обстоятельства (известный набор кодов).

Ответ 2

Я разработчик CKEditor. У нас есть опыт работы с вложенными элементами readonly (т.е. placeholder и функцией, над которой мы работаем в настоящее время # 9764), и у меня нет хороших новостей. Вы должны обрабатывать каждое поведение вручную, если хотите иметь постоянный вид и чувствовать себя. Нет никаких трюков, которые будут исправлять браузеры. И многие вещи (вроде этого со странными вещами, происходящими вокруг ввода на GC) кажутся неразрешимыми.

Ответ 3

Я знаю его старый поток, с которым я столкнулся с подобной проблемой. Просто нужно несколько редактируемых пробелов в редактируемом div. Закончилось внедрение HACK-AROUND, как...

$('#testDiv').on('keydown', function(e) { 
    var targetNode = getSelectionStart();
    if(targetNode != undefined && targetNode.nodeType === 1 && targetNode.nodeName == 'SPAN')    
    {
      var nodeHtmlString = targetNode.outerHTML;

      if(~nodeHtmlString.indexOf("nonEditable"))
      {
        e.preventDefault();
        e.stopPropagation();
      }
    }
});

function getSelectionStart() {
 var node = document.getSelection().anchorNode;
 return (node.nodeType == 3 ? node.parentNode : node);
}

Завершить скрипку https://jsfiddle.net/fxmb3nL6/20/

Ответ 4

Решение ниже - с небольшим предостережением. Но сначала - вы, ребята, потрясающие! Я не эксперт JS или HTML, но я также не знал о jsfiddle.net. Поэтому, читая ваши комментарии, а также другие поисковые запросы в Интернете, а некоторые тесты на jsfiddle я создал следующий код, который работал.

<pre><code>
<div contenteditable="false" class="editor" readonly="true" UNSELECTABLE="ON">
    Sample template with <span class="mergecode test1" />.
    <span contenteditable> editable </span>
    <font color=red><span UNSELECTABLE="ON" contenteditable="false" readonly="true"
     UNSELECTABLE="ON">  uneditable1 </span></font>
    <span contenteditable> editable2 </span>
    <font color=red><span contenteditable=false readonly="true" UNSELECTABLE="ON"> uneditable3</span></font>  
    <span contenteditable> editable4 </span>
    <span contenteditable="false" readonly="true" UNSELECTABLE="ON"> uneditable5 </span>
< /div>
</code></pre>

Если вы поместите это в jsfiddle на chrome, вы увидите, что он работает в chrome (и IE и FF, но немного по-другому), но, похоже, есть небольшой Caveat.

Предостережение - это то, что связывает ваш ключ с Backspace! В моем случае, когда я выбираю неотправляемую фразу и нажимаю backspace в chrome, она, кажется, обновляется или выполняет "переход на последнюю страницу"! Я сделал первые два undeditbles red (оставил последний черный), чтобы вы могли видеть, что происходит. Я тестирую его на jsfiddle в Chrome и в FF и в IE. Все, кажется, действовали должным образом, отдавали или принимали проблему с возвратом.

И я думаю, что вот логика того, как это работает. Первый Div является родителем верхнего уровня, и он доволен = "false". Итак, все под ним должно быть не редактируемым. ЗА ИСКЛЮЧЕНИЕМ детей внутри него, которые имеют span contenteditble = "true", они становятся редактируемыми. Таким образом, вы наследуете от своего родителя, но затем вы можете перезаписать его как ребенка.

Я также помещаю теги readonly = "true" UNSELECTABLE = "ON", потому что я читал о них какое-то место. И потребовалось больше тестирования!!! ПРИМЕЧАНИЕ. ПОЖАЛУЙСТА, мне пришлось взять Font... вне диапазона, иначе это не сработает. Но в IE он работал отлично. Uneditables были тем цветом, который я им сказал, и никакое количество одиночного, dourble или тройного нажатия не выберет uneditbles в jsfiddle!!!:-) Для Chrome один клик ничего не сделал, дважды щелкните выбранный uneditable, и с backspace это пошло немного орехов! Казалось, что это перейдет на предыдущую страницу. С FF вещи были немного сумасшедшими! Дважды щелкните выбранный неотредактируемый и редактируемый перед ним! Не знаю, почему.

Если кто-то может понять и написать о проблемах с Chrome и FF, это было бы здорово. Было бы неплохо иметь двойной клик или любое количество быстрых кликов, чтобы не работать в Chrome и FF. Снова я хочу подчеркнуть, что диапазон... кажется, должен быть рядом с uneditables и шрифтом... вне диапазона.

Надеюсь, что все это имеет смысл.

Ответ 5

Для IE попробуйте это:

<span contenteditable="true">Uneditable</span>

Обратите внимание на обратное значение атрибута contenteditable! Он бросает вызов всему здравому смыслу, но он работает - по крайней мере, в IE8 и IE9. Этот неотредактируемый элемент можно перемещать и копировать/вставлять. Его, однако, далек от совершенства. Например. если вы смеете область, которая включает неотредактируемый элемент, это также приведет к заражению содержимого неотредактируемого элемента. Поэтому вам, вероятно, придется использовать некоторые скрипты, чтобы сохранить разумность элемента. Также установка contenteditable = "true" будет украшать неотредактируемый элемент с помощью ручек изменения размера. Вы можете отключить их снова, установив unselectable = "on", но это предотвратит перетаскивание объекта. Снова вам, вероятно, придется полагаться на script, чтобы восстановить ширину и высоту.