Вставка в приемлемые результаты при случайной вставке тега - PullRequest
3 голосов
/ 16 мая 2011

Я использую поле contentedittable в качестве пользовательского ввода, чтобы я мог использовать форматирование текста. К сожалению, я обнаружил, что когда пользователь вставляет в поле, появляется огромное количество ненужных HTML. Я хочу только простой текст из буфера обмена.

Почему это происходит?!

A Сокращенный пример:

<div><br></div><div><span class="Apple-style-span" style="font-family: Arial, 'Liberation Sans', 'DejaVu Sans', sans-serif; font-size: 13px; line-height: 12px; color: rgb(0, 0, 0); "><table style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; border-collapse: collapse; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; background-position: initial initial; background-repeat: initial initial; "><tbody style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; background-position: initial initial; background-repeat: initial initial; "><tr style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; background-position: initial initial; background-repeat: initial initial; "><td class="votecell" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 13px; vertical-align: top; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; width: 60px; background-position: initial initial; background-repeat: initial initial; "><div class="vote" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; text-align: center; background-position: initial initial; background-repeat: initial initial; "><span class="vote-count-post" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 31px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; display: block; color: rgb(128, 129, 133); font-weight: bold; background-position: initial initial; background-repeat: initial initial; ">1</span><a class="vote-down-off" title="This question does not show any research effort; it is unclear or not useful (click again to undo)" style="margin-top: 0px; margin-right: auto; margin-bottom: 0px; margin-left: auto; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; font-size: 1px; vertical-align: baseline; background-image: url(http://sstatic.net/stackoverflow/img/sprites.png?v=3); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; color: rgb(0, 119, 204); text-decoration: none; cursor: pointer; overflow-x: hidden; overflow-y: hidden; display: block; width: 41px; height: 25px; text-indent: -9999em; background-position: 0px -300px; background-repeat: no-repeat no-repeat; ">...

Ответы [ 2 ]

8 голосов
/ 17 мая 2011

Вы можете получить простой текст, используя взломать.Последние версии как TinyMCE, так и CKEditor используют эту технику в своих редакторах на основе iframe:

  1. Обнаружение Ctrl - v / Shift - Вставить событие с помощью обработчика события нажатия клавиши
  2. В этом обработчике сохранить текущий выбор пользователя, добавить закадровый элемент textarea (скажем, слева -1000px) в документ, повернутьcontentEditable выключить и вызвать focus() для текстовой области, таким образом перемещая каретку и эффективно перенаправляя вставку
  3. Установите очень короткий таймер (скажем, 1 миллисекунду) в обработчике событий для вызова другой функции, которая хранит текстовую областьзначение, удаляет текстовую область из документа, снова включает contentEditable, восстанавливает выбор пользователя и вставляет текст.

Обратите внимание, что это будет работать только для событий вставки с клавиатуры, а не вставок изконтекстные или редактировать меню.Событие paste было бы лучше, но к тому времени, когда оно запускается, уже слишком поздно перенаправлять курсор в текстовую область в большинстве браузеров.

2 голосов
/ 17 мая 2011

Вы получаете всю эту дополнительную ерунду, потому что элемент contenteditable поддерживает тип text/html MIME. Когда вы вставляете что-то из буфера обмена, часто возникает фаза согласования контента:

  • Цель вставки говорит: «Я поддерживаю следующие типы контента: ....»
  • Затем менеджер буфера обмена обсуждает этот список с источником данных, чтобы получить вставленные данные в подходящем формате для цели вставки.
  • И, наконец, данные помещаются в ваш элемент contenteditable как text/html со всем этим дополнительным шумом.

Процесс может отличаться от описанного выше, но он будет аналогичным. Лучше всего было бы добавить обработчик для события paste и использовать этот обработчик для преобразования вставленных данных в text/plain.

...