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>
к вершине выделения, содержащего такой диапазон.
Любые другие идеи?
Ответы
Ответ 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, чтобы восстановить ширину и высоту.