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

Предотвращать создание контекстно-зависимого режима при создании тегов <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);
            });

        });

Но этого недостаточно, так как теоретически теоретически неограниченное количество гнездования может быть неограниченным. Все еще работает над лучшим решением. Любой вход оценивается =)

4b9b3361

Ответ 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