JavaScript получает данные буфера обмена в случае вставки (кросс-браузер)
Как веб-приложение может обнаруживать событие вставки и извлекать данные для вставки?
Я хотел бы удалить содержимое HTML, прежде чем текст будет вставлен в текстовый редактор.
Очистка текста после того, как он будет вставлен впоследствии, но проблема в том, что все предыдущее форматирование потеряно. Например, я могу написать предложение в редакторе и сделать его полужирным, но когда я вставляю новый текст, все форматирование теряется. Я хочу очистить только текст, который вставлен, и оставить любое предыдущее форматирование нетронутым.
В идеале решение должно работать во всех современных браузерах (например, MSIE, Gecko, Chrome и Safari).
Обратите внимание, что MSIE имеет clipboardData.getData()
, но я не смог найти аналогичную функциональность для других браузеров.
Ответы
Ответ 1
Ситуация изменилась с момента написания этого ответа: теперь, когда Firefox добавила поддержку в версии 22, все основные браузеры теперь поддерживают доступ к данным буфера обмена в событии вставки. См. Ответ Нико Бернса для примера.
В прошлом это не было возможно вообще в кросс-браузере. Идеальным было бы получить вставляемый контент через событие paste
, что возможно в последних браузерах, но не в некоторых старых браузерах (в частности, Firefox < 22).
Когда вам нужно поддерживать более старые браузеры, то, что вы можете сделать, довольно востребовано и немного взломать, что будет работать в браузерах Firefox 2+, IE 5.5+ и WebKit, таких как Safari или Chrome. Последние версии TinyMCE и CKEditor используют эту технику:
- Обнаружение события ctrl-v/shift-ins с помощью обработчика событий нажатия клавиш
- В этом обработчике сохраните текущий выбор пользователя, добавьте элемент textarea за пределы экрана (скажем, левый -1000px) к документу, отключите
designMode
и вызовите focus()
на текстовое поле, таким образом, перемещая каретку и эффективно перенаправлять пасту
- Установите очень короткий таймер (например, 1 миллисекунду) в обработчике событий, чтобы вызвать другую функцию, которая сохраняет значение textarea, удаляет текстовое поле из документа, снова включает
designMode
, восстанавливает выбор пользователя и вставляет текст в.
Обратите внимание, что это будет работать только для событий вставки клавиатуры, а не из паст в контекстном меню или в меню редактирования. К тому времени, когда срабатывает событие пасты, слишком поздно перенаправить курсор в текстовое поле (по крайней мере, в некоторых браузерах).
В маловероятном случае, когда вам нужно поддерживать Firefox 2, обратите внимание, что вам нужно разместить текстовое поле в родительском документе, а не в документе iframe редактора WYSIWYG в этом браузере.
Ответ 2
Решение № 1 (только обычный текст и требуется Firefox 22 +)
Работает для IE6 +, FF 22+, Chrome, Safari, Edge
(Тестируется только в IE9 +, но должен работать для более низких версий)
Если вам нужна поддержка для вставки HTML или Firefox <= 22, см. Решение № 2.
HTML
<div id='editableDiv' contenteditable='true'>Paste</div>
JavaScript
function handlePaste (e) {
var clipboardData, pastedData;
// Stop data actually being pasted into div
e.stopPropagation();
e.preventDefault();
// Get pasted data via clipboard API
clipboardData = e.clipboardData || window.clipboardData;
pastedData = clipboardData.getData('Text');
// Do whatever with pasteddata
alert(pastedData);
}
document.getElementById('editableDiv').addEventListener('paste', handlePaste);
JSFiddle: https://jsfiddle.net/swL8ftLs/12/
Обратите внимание, что это решение использует параметр "Текст" для функции getData
, что является нестандартным. Однако он работает во всех браузерах на момент написания.
Решение №2 (HTML и работает для Firefox <= 22)
Протестировано в IE6 +, FF 3.5+, Chrome, Safari, Edge
HTML
<div id='div' contenteditable='true'>Paste</div>
JavaScript
var editableDiv = document.getElementById('editableDiv');
function handlepaste (e) {
var types, pastedData, savedContent;
// Browsers that support the 'text/html' type in the Clipboard API (Chrome, Firefox 22+)
if (e && e.clipboardData && e.clipboardData.types && e.clipboardData.getData) {
// Check for 'text/html' in types list. See abligh answer below for deatils on
// why the DOMStringList bit is needed. We cannot fall back to 'text/plain' as
// Safari/Edge don't advertise HTML data even if it is available
types = e.clipboardData.types;
if (((types instanceof DOMStringList) && types.contains("text/html")) || (types.indexOf && types.indexOf('text/html') !== -1)) {
// Extract data and pass it to callback
pastedData = e.clipboardData.getData('text/html');
processPaste(editableDiv, pastedData);
// Stop the data from actually being pasted
e.stopPropagation();
e.preventDefault();
return false;
}
}
// Everything else: Move existing element contents to a DocumentFragment for safekeeping
savedContent = document.createDocumentFragment();
while(editableDiv.childNodes.length > 0) {
savedContent.appendChild(editableDiv.childNodes[0]);
}
// Then wait for browser to paste content into it and cleanup
waitForPastedData(editableDiv, savedContent);
return true;
}
function waitForPastedData (elem, savedContent) {
// If data has been processes by browser, process it
if (elem.childNodes && elem.childNodes.length > 0) {
// Retrieve pasted content via innerHTML
// (Alternatively loop through elem.childNodes or elem.getElementsByTagName here)
var pastedData = elem.innerHTML;
// Restore saved content
elem.innerHTML = "";
elem.appendChild(savedContent);
// Call callback
processPaste(elem, pastedData);
}
// Else wait 20ms and try again
else {
setTimeout(function () {
waitForPastedData(elem, savedContent)
}, 20);
}
}
function processPaste (elem, pastedData) {
// Do whatever with gathered data;
alert(pastedData);
elem.focus();
}
// Modern browsers. Note: 3rd argument is required for Firefox <= 6
if (editableDiv.addEventListener) {
editableDiv.addEventListener('paste', handlepaste, false);
}
// IE <= 8
else {
editableDiv.attachEvent('onpaste', handlepaste);
}
JSFiddle: https://jsfiddle.net/nicoburns/wrqmuabo/23/
Объяснение
Событие onpaste
для div
имеет прикрепленную к нему функцию handlePaste
и передает один аргумент: объект event
для события вставки. Особый интерес для нас представляет свойство clipboardData
этого события, которое обеспечивает доступ к буферам обмена в браузерах, отличных от ie. В IE эквивалент это window.clipboardData
, хотя это имеет несколько иной API.
См. раздел ресурсов ниже.
Функция handlePaste
:
Эта функция имеет две ветки.
Первая проверяет существование event.clipboardData
и проверяет, содержит ли это свойство types
'text/html' (types
может быть либо DOMStringList
, который проверяется с помощью метода contains
, либо строка, которая проверяется с помощью метода indexOf
). Если все эти условия выполнены, то мы будем действовать так же, как и в решении # 1, за исключением "text/html" вместо "text/plain". Это в настоящее время работает в Chrome и Firefox 22 +.
Если этот метод не поддерживается (все остальные браузеры), мы
- Сохраните содержимое элемента в
DocumentFragment
- Очистить элемент
- Вызвать функцию
waitForPastedData
Функция waitforpastedata
:
Эта функция сначала опроса для вставленных данных (один раз за 20 мс), что необходимо, потому что она не появляется сразу. Когда появились данные, это:
- Сохраняет innerHTML редактируемого div (который теперь вставляет данные) в переменную
- Восстанавливает содержимое, сохраненное в DocumentFragment
- Вызывает функцию processPaste с извлеченными данными
Функция processpaste
:
Производит ли какие-либо вещи со вставленными данными. В этом случае мы просто предупреждаем данные, вы можете делать все, что захотите. Вероятно, вы захотите запустить вложенные данные через какой-то процесс дезактивации данных.
Сохранение и восстановление положения курсора
В реальной постановке вы, вероятно, захотите сохранить выделение раньше и затем восстановить его (Установить положение курсора на contentEditable <div> ). Затем вы можете вставить вставленные данные в позицию, в которой находился курсор, когда пользователь начал действие вставки.
Ресурсы:
Благодаря Тиму Дауну предлагается использовать DocumentFragment и аббревиатуру для обнаружения ошибки в Firefox из-за использования DOMStringList вместо строки для clipboardData.types
Ответ 3
Простая версия: (jQuery)
$(document).on('paste','[contenteditable]',function(e) {
e.preventDefault();
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
window.document.execCommand('insertText', false, text);
});
Использование clipboardData
Демо: http://jsbin.com/vokovividu/edit?js,output
IE Edge, Firefox, Chrome, Safari, Opera протестированы.
Ответ 4
Live Demo
Протестировано в Chrome/FF/IE11
Существует раздражение Chrome/IE, которое заключается в том, что эти браузеры добавляют элемент <div>
для каждой новой строки. Здесь есть сообщение об этом , и его можно устранить, установив элемент contenteditable равным display:inline-block
Выберите выделенный HTML-код и вставьте его здесь:
function onPaste(e){
var content;
e.preventDefault();
if( e.clipboardData ){
content = e.clipboardData.getData('text/plain');
document.execCommand('insertText', false, content);
return false;
}
else if( window.clipboardData ){
content = window.clipboardData.getData('Text');
if (window.getSelection)
window.getSelection().getRangeAt(0).insertNode( document.createTextNode(content) );
}
}
/////// EVENT BINDING /////////
document.querySelector('[contenteditable]').addEventListener('paste', onPaste);
[contenteditable]{
/* chroem bug: https://stackoverflow.com/a/24689420/104380 */
display:inline-block;
width: calc(100% - 40px);
min-height:120px;
margin:10px;
padding:10px;
border:1px dashed green;
}
/*
mark HTML inside the "contenteditable"
(Shouldn't be any OFC!)'
*/
[contenteditable] *{
background-color:red;
}
<div contenteditable></div>
Ответ 5
Я написал небольшое доказательство концепции для предложения Тима Даунса с текстовым полем вне экрана. И вот код:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script language="JavaScript">
$(document).ready(function()
{
var ctrlDown = false;
var ctrlKey = 17, vKey = 86, cKey = 67;
$(document).keydown(function(e)
{
if (e.keyCode == ctrlKey) ctrlDown = true;
}).keyup(function(e)
{
if (e.keyCode == ctrlKey) ctrlDown = false;
});
$(".capture-paste").keydown(function(e)
{
if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)){
$("#area").css("display","block");
$("#area").focus();
}
});
$(".capture-paste").keyup(function(e)
{
if (ctrlDown && (e.keyCode == vKey || e.keyCode == cKey)){
$("#area").blur();
//do your sanitation check or whatever stuff here
$("#paste-output").text($("#area").val());
$("#area").val("");
$("#area").css("display","none");
}
});
});
</script>
</head>
<body class="capture-paste">
<div id="paste-output"></div>
<div>
<textarea id="area" style="display: none; position: absolute; left: -99em;"></textarea>
</div>
</body>
</html>
Просто скопируйте и вставьте весь код в один файл html и попробуйте вставить (используя ctrl-v) текст из буфера обмена в любом месте документа.
Я тестировал его в IE9 и новых версиях Firefox, Chrome и Opera. Хорошо работает. Также хорошо, что можно использовать любую комбинацию клавиш, которую он предпочитает использовать эту функцию. Конечно, не забудьте включить источники jQuery.
Не стесняйтесь использовать этот код, и если вы придете с некоторыми улучшениями или проблемами, отправьте их обратно. Также обратите внимание, что я не разработчик Javascript, поэтому я, возможно, что-то пропустил (= > сделать свой собственный тест).
Ответ 6
На основе l2aelba anwser. Это было проверено на FF, Safari, Chrome, IE (8,9,10 и 11).
$("#editText").on("paste", function (e) {
e.preventDefault();
var text;
var clp = (e.originalEvent || e).clipboardData;
if (clp === undefined || clp === null) {
text = window.clipboardData.getData("text") || "";
if (text !== "") {
if (window.getSelection) {
var newNode = document.createElement("span");
newNode.innerHTML = text;
window.getSelection().getRangeAt(0).insertNode(newNode);
} else {
document.selection.createRange().pasteHTML(text);
}
}
} else {
text = clp.getData('text/plain') || "";
if (text !== "") {
document.execCommand('insertText', false, text);
}
}
});
Ответ 7
В этом случае не используется setTimeout().
Я использовал эту отличную статью, чтобы получить поддержку кросс-браузера.
$(document).on("focus", "input[type=text],textarea", function (e) {
var t = e.target;
if (!$(t).data("EventListenerSet")) {
//get length of field before paste
var keyup = function () {
$(this).data("lastLength", $(this).val().length);
};
$(t).data("lastLength", $(t).val().length);
//catch paste event
var paste = function () {
$(this).data("paste", 1);//Opera 11.11+
};
//process modified data, if paste occured
var func = function () {
if ($(this).data("paste")) {
alert(this.value.substr($(this).data("lastLength")));
$(this).data("paste", 0);
this.value = this.value.substr(0, $(this).data("lastLength"));
$(t).data("lastLength", $(t).val().length);
}
};
if (window.addEventListener) {
t.addEventListener('keyup', keyup, false);
t.addEventListener('paste', paste, false);
t.addEventListener('input', func, false);
}
else {//IE
t.attachEvent('onkeyup', function () {
keyup.call(t);
});
t.attachEvent('onpaste', function () {
paste.call(t);
});
t.attachEvent('onpropertychange', function () {
func.call(t);
});
}
$(t).data("EventListenerSet", 1);
}
});
Этот код расширен с помощью дескриптора выделения перед вставкой:
демо
Ответ 8
Для очистки вложенного текста и , заменяя выделенный текст текстом, вопрос довольно тривиален:
<div id='div' contenteditable='true' onpaste='handlepaste(this, event)'>Paste</div>
JS:
function handlepaste(el, e) {
document.execCommand('insertText', false, e.clipboardData.getData('text/plain'));
e.preventDefault();
}
Ответ 9
Решение, которое работает для меня, добавляет прослушиватель событий, чтобы вставить событие, если вы вставляете текстовый ввод.
Поскольку событие вставки происходит перед текстом во входных изменениях, внутри моего обработчика пасты я создаю отложенную функцию, внутри которой я проверяю изменения в моем поле ввода, которое произошло при вставке:
onPaste: function() {
var oThis = this;
setTimeout(function() { // Defer until onPaste() is done
console.log('paste', oThis.input.value);
// Manipulate pasted input
}, 1);
}
Ответ 10
Это должно работать на всех браузерах, поддерживающих событие onpaste и наблюдателя мутаций.
Это решение выходит за рамки получения текста, оно фактически позволяет вам редактировать вставленный контент, прежде чем он будет вставлен в элемент.
Он работает с использованием контента contenteditable, onpaste (поддерживается всеми основными браузерами) en mutation observers (поддерживается Chrome, Firefox и IE11 +)
шаг 1
Создайте HTML-элемент с contenteditable
<div contenteditable="true" id="target_paste_element"></div>
шаг 2
В вашем Javascript-коде добавьте следующее событие
document.getElementById("target_paste_element").addEventListener("paste", pasteEventVerifierEditor.bind(window, pasteCallBack), false);
Нам нужно связать pasteCallBack, так как наблюдатель мутации будет вызываться асинхронно.
шаг 3
Добавьте в свой код
следующую функцию:
function pasteEventVerifierEditor(callback, e)
{
//is fired on a paste event.
//pastes content into another contenteditable div, mutation observer observes this, content get pasted, dom tree is copied and can be referenced through call back.
//create temp div
//save the caret position.
savedCaret = saveSelection(document.getElementById("target_paste_element"));
var tempDiv = document.createElement("div");
tempDiv.id = "id_tempDiv_paste_editor";
//tempDiv.style.display = "none";
document.body.appendChild(tempDiv);
tempDiv.contentEditable = "true";
tempDiv.focus();
//we have to wait for the change to occur.
//attach a mutation observer
if (window['MutationObserver'])
{
//this is new functionality
//observer is present in firefox/chrome and IE11
// select the target node
// create an observer instance
tempDiv.observer = new MutationObserver(pasteMutationObserver.bind(window, callback));
// configuration of the observer:
var config = { attributes: false, childList: true, characterData: true, subtree: true };
// pass in the target node, as well as the observer options
tempDiv.observer.observe(tempDiv, config);
}
}
function pasteMutationObserver(callback)
{
document.getElementById("id_tempDiv_paste_editor").observer.disconnect();
delete document.getElementById("id_tempDiv_paste_editor").observer;
if (callback)
{
//return the copied dom tree to the supplied callback.
//copy to avoid closures.
callback.apply(document.getElementById("id_tempDiv_paste_editor").cloneNode(true));
}
document.body.removeChild(document.getElementById("id_tempDiv_paste_editor"));
}
function pasteCallBack()
{
//paste the content into the element.
restoreSelection(document.getElementById("target_paste_element"), savedCaret);
delete savedCaret;
pasteHtmlAtCaret(this.innerHTML, false, true);
}
saveSelection = function(containerEl) {
if (containerEl == document.activeElement)
{
var range = window.getSelection().getRangeAt(0);
var preSelectionRange = range.cloneRange();
preSelectionRange.selectNodeContents(containerEl);
preSelectionRange.setEnd(range.startContainer, range.startOffset);
var start = preSelectionRange.toString().length;
return {
start: start,
end: start + range.toString().length
};
}
};
restoreSelection = function(containerEl, savedSel) {
containerEl.focus();
var charIndex = 0, range = document.createRange();
range.setStart(containerEl, 0);
range.collapse(true);
var nodeStack = [containerEl], node, foundStart = false, stop = false;
while (!stop && (node = nodeStack.pop())) {
if (node.nodeType == 3) {
var nextCharIndex = charIndex + node.length;
if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
range.setStart(node, savedSel.start - charIndex);
foundStart = true;
}
if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
range.setEnd(node, savedSel.end - charIndex);
stop = true;
}
charIndex = nextCharIndex;
} else {
var i = node.childNodes.length;
while (i--) {
nodeStack.push(node.childNodes[i]);
}
}
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
function pasteHtmlAtCaret(html, returnInNode, selectPastedContent) {
//function written by Tim Down
var sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// only relatively recently standardized and is not supported in
// some browsers (IE9, for one)
var el = document.createElement("div");
el.innerHTML = html;
var frag = document.createDocumentFragment(), node, lastNode;
while ( (node = el.firstChild) ) {
lastNode = frag.appendChild(node);
}
var firstNode = frag.firstChild;
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
if (returnInNode)
{
range.setStart(lastNode, 0); //this part is edited, set caret inside pasted node.
}
else
{
range.setStartAfter(lastNode);
}
if (selectPastedContent) {
range.setStartBefore(firstNode);
} else {
range.collapse(true);
}
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if ( (sel = document.selection) && sel.type != "Control") {
// IE < 9
var originalRange = sel.createRange();
originalRange.collapse(true);
sel.createRange().pasteHTML(html);
if (selectPastedContent) {
range = sel.createRange();
range.setEndPoint("StartToStart", originalRange);
range.select();
}
}
}
Что делает код:
- Кто-то запускает событие вставки с помощью ctrl-v, contextmenu или других средств.
- В событии вставки создается новый элемент с contenteditable (элемент с contenteditable имеет повышенные привилегии)
- Позиция каретки целевого элемента сохраняется.
- Фокус установлен на новый элемент
- Содержимое вставляется в новый элемент и отображается в DOM.
- Наблюдатель за мутацией ловит это (он регистрирует все изменения в дереве и контенте). Затем запускается событие мутации.
- Домен вставляемого содержимого клонируется в переменную и возвращается к обратному вызову. Временный элемент уничтожен.
- Обратный вызов получает клонированную DOM. Каретка восстанавливается. Вы можете отредактировать это, прежде чем присоединять его к своей цели. элемент. В этом примере я использую функции Tim Downs для сохранения/восстановления каретки и вставки HTML в элемент.
Большое спасибо Tim Down
Ответьте на это сообщение:
Получить вставленный контент в документе при вставке
Ответ 11
Это слишком долго для комментария к ответу Nico, который, как я уже не думаю, больше работает на Firefox (по комментариям), и не работал у меня в Safari, как есть.
Во-первых, вы теперь можете читать непосредственно из буфера обмена. Вместо кода вроде:
if (/text\/plain/.test(e.clipboardData.types)) {
// shouldn't this be writing to elem.value for text/plain anyway?
elem.innerHTML = e.clipboardData.getData('text/plain');
}
использование:
types = e.clipboardData.types;
if (((types instanceof DOMStringList) && types.contains("text/plain")) ||
(/text\/plain/.test(types))) {
// shouldn't this be writing to elem.value for text/plain anyway?
elem.innerHTML = e.clipboardData.getData('text/plain');
}
потому что Firefox имеет поле types
, которое является DOMStringList
, которое не реализует test
.
Далее Firefox не разрешит вставку, если фокус не находится в поле contenteditable=true
.
Наконец, Firefox не допустит вставки, если фокус находится в textarea
(или, возможно, вводе), который не только contenteditable=true
, но также:
- not
display:none
- not
visibility:hidden
- не нулевой размер
Я пытался скрыть текстовое поле, чтобы я мог сделать работу пасты над эмулятором JS VNC (т.е. он направлялся к удаленному клиенту, и на самом деле не было textarea
и т.д.). Я обнаружил, что попытка скрыть текстовое поле в приведенном выше примере дала симптомы, где она работала иногда, но обычно не выполнялась во второй паре (или когда поле было очищено, чтобы предотвратить вставку одних и тех же данных дважды), поскольку поле потеряло фокус и не восстановилось должным образом это несмотря на focus()
. Решение, с которым я столкнулся, состояло в том, чтобы положить его на z-order: -1000
, сделать его display:none
, сделать его как 1px на 1px и установить все цвета в прозрачные. Тьфу.
В Safari вы выполняете вторую часть вышеизложенного, т.е. вам нужно иметь textarea
, который не является display:none
.
Ответ 12
Во-первых, что приходит в голову, это пастордлер google закрытия lib
http://closure-library.googlecode.com/svn/trunk/closure/goog/demos/pastehandler.html
Ответ 13
Это сработало для меня:
function onPasteMe(currentData, maxLen) {
// validate max length of pasted text
var totalCharacterCount = window.clipboardData.getData('Text').length;
}
<input type="text" onPaste="return onPasteMe(this, 50);" />
Ответ 14
Это решение заменяет тэг html, он простой и кросс-браузер; проверьте этот jsfiddle: http://jsfiddle.net/tomwan/cbp1u2cx/1/, код ядра:
var $plainText = $("#plainText");
var $linkOnly = $("#linkOnly");
var $html = $("#html");
$plainText.on('paste', function (e) {
window.setTimeout(function () {
$plainText.html(removeAllTags(replaceStyleAttr($plainText.html())));
}, 0);
});
$linkOnly.on('paste', function (e) {
window.setTimeout(function () {
$linkOnly.html(removeTagsExcludeA(replaceStyleAttr($linkOnly.html())));
}, 0);
});
function replaceStyleAttr (str) {
return str.replace(/(<[\w\W]*?)(style)([\w\W]*?>)/g, function (a, b, c, d) {
return b + 'style_replace' + d;
});
}
function removeTagsExcludeA (str) {
return str.replace(/<\/?((?!a)(\w+))\s*[\w\W]*?>/g, '');
}
function removeAllTags (str) {
return str.replace(/<\/?(\w+)\s*[\w\W]*?>/g, '');
}
Обратите внимание: вы должны выполнить некоторую работу с фильтром xss на обратной стороне, потому что это решение не может фильтровать строки, такие как '< < → '
Ответ 15
Вы можете сделать это следующим образом:
используйте этот плагин jQuery для событий pre и post paste:
$.fn.pasteEvents = function( delay ) {
if (delay == undefined) delay = 20;
return $(this).each(function() {
var $el = $(this);
$el.on("paste", function() {
$el.trigger("prepaste");
setTimeout(function() { $el.trigger("postpaste"); }, delay);
});
});
};
Теперь вы можете использовать этот плагин;
$('#txt').on("prepaste", function() {
$(this).find("*").each(function(){
var tmp=new Date.getTime();
$(this).data("uid",tmp);
});
}).pasteEvents();
$('#txt').on("postpaste", function() {
$(this).find("*").each(function(){
if(!$(this).data("uid")){
$(this).removeClass();
$(this).removeAttr("style id");
}
});
}).pasteEvents();
Explaination
Сначала установите uid для всех существующих элементов как атрибут данных.
Затем сравните все события POST PASTE узлов. Поэтому, сравнивая, вы можете идентифицировать вновь вставленный, потому что у них будет uid, а затем просто удалите атрибут style/class/id из вновь созданных элементов, чтобы вы могли сохранить прежнее форматирование.
Ответ 16
$('#dom').on('paste',function (e){
setTimeout(function(){
console.log(e.currentTarget.value);
},0);
});
Ответ 17
Просто позвольте браузеру вставлять как обычно в свой контентный редактируемый div, а затем после того, как паста заменит любые элементы диапазона, используемые для пользовательских стилей текста, с самим текстом. Это похоже на работу в Internet Explorer и других браузерах, которые я пробовал...
$('[contenteditable]').on('paste', function (e) {
setTimeout(function () {
$(e.target).children('span').each(function () {
$(this).replaceWith($(this).text());
});
}, 0);
});
В этом решении предполагается, что вы используете jQuery, а не хотите форматировать текст в любом из ваших редактируемых разделов контента.
Положительная сторона - это просто супер.
Ответ 18
function myFunct( e ){
e.preventDefault();
var pastedText = undefined;
if( window.clipboardData && window.clipboardData.getData ){
pastedText = window.clipboardData.getData('Text');
}
else if( e.clipboardData && e.clipboardData.getData ){
pastedText = e.clipboardData.getData('text/plain');
}
//work with text
}
document.onpaste = myFunct;
Ответ 19
Это уже существующий код, но я обновил его для IE, ошибка была тогда, когда существующий текст был выбран и вставлен не удалит выбранное содержимое. Это было исправлено с помощью приведенного ниже кода
selRange.deleteContents();
Смотрите полный код ниже
$('[contenteditable]').on('paste', function (e) {
e.preventDefault();
if (window.clipboardData) {
content = window.clipboardData.getData('Text');
if (window.getSelection) {
var selObj = window.getSelection();
var selRange = selObj.getRangeAt(0);
selRange.deleteContents();
selRange.insertNode(document.createTextNode(content));
}
} else if (e.originalEvent.clipboardData) {
content = (e.originalEvent || e).clipboardData.getData('text/plain');
document.execCommand('insertText', false, content);
}
});