Предотвращать создание контекстно-зависимого режима при создании тегов <span>
Когда я использую браузер contenteditable = true в div, чтобы позволить пользователю обновлять текст в нем, я сталкиваюсь с этой проблемой (используя Chrome):
При использовании клавиши backspace delete для удаления разрыва строки (переход вверх по строке) браузер вставляет тег с встроенным набором стилей вокруг этого текста.
Это действительно разочаровывает, потому что это не только делает это, но также добавляет встроенный стиль этому тегу span, например, если мой цвет шрифта в настоящее время является черным, он добавляет к этому тегу span стиль = "color: black",
В результате я больше не могу редактировать цвет этого текста с помощью моей панели инструментов, так как он был привязан к тегу span встроенным стилем. То же самое происходит с размером шрифта, если я делаю то же самое, резервное копирование строки с помощью ключа удаления.
Любой, кто мог бы научить меня чему-то доволенному или предложить способ удалить span: s, если это невозможно предотвратить это поведение браузера.
** Чтобы воспроизвести эту проблему **
- Создайте div в браузере, установите для него встроенный стиль, например, размером шрифта: 36px
- Редактируйте текст div с содержимым, редактируемым в браузере, напишите пару строк с ручными разрывами строк.
- Теперь поместите курсор в FRONT OF/BEFORE в абзац текста и нажмите backspace. Тег span должен теперь генерироваться вокруг текста, который находится в FRONT вашего курсора, и стиль его изменился.
ОБНОВЛЕНИЕ **
Поэтому я пробовал несколько разных решений с ограниченным успехом. Сначала я попытался удалить все теги, но потом я потерял все линейные разрывы (возможно, лучшее регулярное выражение могло бы решить эту проблему, я не специалист по записи regExp).
Все функции, приведенные ниже, сначала вызывались при событии keyup, но затем я привязал их, чтобы отменить выбор текстового поля. Как срабатывать ниже функции не имеет значения для вопроса.
//option to remove all tags
var withTags = $(textObject).html();
var withoutTags = withTags.replace(/<(?:.|\n)*?>/gm, '');
$(textObject).html(withoutTags);
Моя вторая попытка была более успешной, удалив теги стиля объектов под текстовым полем (divs ans охватывает внутри текстового поля, добавленного хром), вот мой первый код
//option to remove style of elements
$(textObject).children().each(function() {
$(this).removeAttr('style');
console.log('removing style from first level element: '+this);
});
Затем я понял, что каждый раз, когда я редактирую текстовое поле, chrome может добавить новый вложенный уровень тегов div/span, который не будет указан выше, поэтому я сделал это:
//option to remove style of elements
$(textObject).children().each(function() {
$(this).removeAttr('style');
console.log('removing style from first level element: '+this);
//And of course it would be all too easy if chrome added only one level of elements...
$(this).children().each(function() {
$(this).removeAttr('style');
console.log('removing style from second level element: '+this);
});
});
Но этого недостаточно, так как теоретически теоретически неограниченное количество гнездования может быть неограниченным. Все еще работает над лучшим решением. Любой вход оценивается =)
Ответы
Ответ 1
Вот как я решил это
jquery remove <span> при сохранении их содержимого (и заменить <divs> и <p> s с <br> )
Я сохраняю текст всех тегов div, span и p, удаляю те теги и заменяю все div и p на br. Я делаю это на размытие, оптимальным было бы сделать это при каждом нажатии клавиши, но это слишком много процессора, так как я должен пройти все эти% # ¤¤% & (вы сказали) вложенные элементы.
Ответ 2
Проблема заключается в том, что не только он вставляет span и p, но если вам удастся скопировать таблицу, она будет вставлять всю таблицу с телом и строками.
Итак, единственный способ справиться с этим, который я нашел для меня, - это:
$(document).on("DOMNodeInserted", $.proxy(function (e) {
if (e.target.parentNode.getAttribute("contenteditable") === "true") {
with (e.target.parentNode) {
replaceChild(e.target.firstChild, e.target);
normalize();
}
}
}, this));
Да, это несколько влияет на чрезмерную производительность страницы, но блокирует вставку таблиц и т.д. в contenteditables.
UPDATE:
script выше обрабатывает только основные случаи, когда содержимое, которое вы хотите, обернуто на один уровень тэгов span/p. Однако, если вы скопируете, скажем, Word, вы можете закончить копирование даже всех таблиц.
Итак, вот код, который обрабатывает все, что я на него набросал:
$(document).on("DOMNodeInserted", $.proxy(function (e) {
if (e.target.parentNode.getAttribute("contenteditable") === "true") {
var newTextNode = document.createTextNode("");
function antiChrome(node) {
if (node.nodeType == 3) {
newTextNode.nodeValue += node.nodeValue.replace(/(\r\n|\n|\r)/gm, "")
}
else if (node.nodeType == 1 && node.childNodes) {
for (var i = 0; i < node.childNodes.length; ++i) {
antiChrome(node.childNodes[i]);
}
}
}
antiChrome(e.target);
e.target.parentNode.replaceChild(newTextNode, e.target);
}
}, this));
Кроме того, не стесняйтесь изменять регулярное выражение в середине любым способом, который вам нравится удалять символы, которые особенно опасны в вашем случае.
ОБНОВЛЕНИЕ 2
Немного подумав и поглядывая, я просто завернул код выше в простой плагин jQuery, чтобы облегчить его использование. Вот ссылка GitHub
Ответ 3
В настоящее время я использую
$(textObject).find('*').removeAttr('style');
после отмены выбора области редактирования.
Его также можно использовать при активации клавиатуры.
Ответ 4
Человек, время на этот вопрос сумасшедшее. То, что я делаю с contenteditable, заставляет весь контент находиться в тегах абзаца, содержащего контент div.
Таким образом, я обрабатываю эту фигуру дерьма, которая создается, путем сглаживания каждого <p>
при каждом нажатии клавиши.
Так как .text()
выбирает ВСЕ текст элемента, включая его подэлементы, я могу просто установить (в coffeescript)
t = $(element).text()
$(element).children().remove()
$(element).text(t)
Что решает мою проблему. Как и в стороне, эти разработчики браузеров действительно сильно испортили контент. Здесь есть огромная возможность сделать это легко, потому что это действительно будущее Интернета.
Ответ 5
Добавить стиль отображения: встроенный блок; к contenteditable, он не будет генерировать div, p, span automatic в chrome