Comment une application Web peut-elle détecter un événement de collage et récupérer les données à coller?
Je souhaite supprimer le contenu HTML avant que le texte ne soit collé dans un éditeur de texte enrichi.
Nettoyer le texte après avoir été collé par la suite fonctionne, mais le problème est que tout le formatage précédent est perdu. Par exemple, je peux écrire une phrase dans l'éditeur et la mettre en gras, mais lorsque je colle un nouveau texte, toute la mise en forme est perdue. Je souhaite nettoyer uniquement le texte collé et ne pas toucher au formatage précédent.
Idéalement, la solution devrait fonctionner sur tous les navigateurs modernes (MSIE, Gecko, Chrome et Safari, par exemple).
Notez que MSIE a clipboardData.getData()
, mais je n’ai pas trouvé de fonctionnalité similaire pour les autres navigateurs.
La situation a changé depuis l'écriture de cette réponse: maintenant que Firefox a ajouté la prise en charge de la version 22, tous les principaux navigateurs prennent désormais en charge l'accès aux données du Presse-papiers dans un événement de collage. Voir réponse de Nico Burns pour un exemple.
Dans le passé, cela n’était généralement pas possible de manière transversale. L'idéal serait de pouvoir obtenir le contenu collé via l'événement paste
, ce qui est possible dans les navigateurs récents , mais pas dans certains navigateurs plus anciens (notamment Firefox <22).
Lorsque vous devez prendre en charge des navigateurs plus anciens, ce que vous pouvez faire est très complexe et nécessite un peu de bidouille qui fonctionnera dans les navigateurs Firefox 2+, IE 5.5+ et WebKit tels que Safari ou Chrome. Les versions récentes de TinyMCE et de CKEditor utilisent cette technique:
designMode
et appelez focus()
sur la zone de texte, déplaçant ainsi le curseur. et rediriger efficacement la pâtedesignMode
, restaure la sélection de l'utilisateur et insère le texte.Notez que cela ne fonctionnera que pour les événements de collage au clavier et non pour les pâtes du menu contextuel ou d'édition. Au moment du déclenchement de l'événement coller, il est trop tard pour rediriger le curseur dans la zone de texte (du moins dans certains navigateurs).
Dans le cas peu probable où vous auriez besoin de supporter Firefox 2, notez que vous devez placer la zone de texte dans le document parent plutôt que le document iframe de l'éditeur WYSIWYG dans ce navigateur.
Fonctionne pour IE6 +, FF 22+, Chrome, Safari, Edge (Testé uniquement dans IE9 +, mais devrait fonctionner pour les versions inférieures)
Si vous avez besoin d'assistance pour coller HTML ou Firefox <= 22, voir la solution n ° 2.
<div id='editableDiv' contenteditable='true'>Paste</div>
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/
Notez que cette solution utilise le paramètre 'Text' pour la fonction getData
, qui est non standard. Cependant, cela fonctionne dans tous les navigateurs au moment de l'écriture.
Testé dans IE6 +, FF 3.5+, Chrome, Safari, Edge
<div id='div' contenteditable='true'>Paste</div>
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's 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/
L'événement onpaste
de div
est associé à la fonction handlePaste
et passe un argument unique: l'objet event
de l'événement de collage. La propriété clipboardData
de cet événement nous intéresse particulièrement, car elle permet l’accès au Presse-papiers dans les navigateurs autres que les navigateurs. Dans IE, l'équivalent est window.clipboardData
, bien que son API soit légèrement différente.
Voir la section ressources ci-dessous.
La fonction handlepaste
:
Cette fonction a deux branches.
La première vérifie l'existence de event.clipboardData
et vérifie si sa propriété types
contient 'text/html' (types
peut être une DOMStringList
qui est vérifiée à l'aide de la commande contains
ou une chaîne vérifiée à l'aide de la méthode indexOf
. Si toutes ces conditions sont remplies, nous procédons comme dans la solution n ° 1, à l'exception de 'text/html' au lieu de 'text/plain'. Cela fonctionne actuellement dans Chrome et Firefox 22+.
Si cette méthode n'est pas supportée (tous les autres navigateurs), alors nous
DocumentFragment
waitForPastedData
La fonction waitforpastedata
:
Cette fonction interroge d'abord les données collées (une fois par 20 ms), ce qui est nécessaire car elles n'apparaissent pas immédiatement. Lorsque les données sont apparues, il:
La fonction processpaste
:
Fait des choses arbitraires avec les données collées. Dans ce cas, nous alertons simplement les données, vous pouvez faire ce que vous voulez. Vous voudrez probablement exécuter les données collées via un processus de désinfection des données.
Sauvegarde et restauration de la position du curseur
Dans une situation réelle, vous souhaiterez probablement enregistrer la sélection avant, puis la restaurer ( Définir la position du curseur sur contentEditable <div> ). Vous pouvez ensuite insérer les données collées à la position du curseur lorsque l'utilisateur a initié l'action de collage.
Merci à Tim Down d’avoir suggéré l’utilisation d’un DocumentFragment et d’avoir détecté une erreur dans Firefox due à l’utilisation de DOMStringList au lieu d’une chaîne pour clipboardData.types
Version simple:
document.querySelector('[contenteditable]').addEventListener('paste', (e) => {
e.preventDefault();
const text = (e.originalEvent || e).clipboardData.getData('text/plain');
window.document.execCommand('insertText', false, text);
});
Utilisation de clipboardData
Démo: http://jsbin.com/nozifexasu/edit?js,output
Edge, Firefox, Chrome, Safari, Opera testé.
Remarque: N'oubliez pas de vérifier les entrées/sorties sur côté serveur également ( comme PHP strip-tags )
Testé sur Chrome/FF/IE11
Il existe un inconvénient pour Chrome/IE: ces navigateurs ajoutent un élément <div>
à chaque nouvelle ligne. Il y a un article à ce sujet ici et il peut être corrigé en définissant l'élément contenteditable sur display:inline-block
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>
J'ai rédigé une petite preuve de concept pour la proposition de Tim Downs ici avec textarea hors écran. Et voici le code:
<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>
Il suffit de copier et coller le code entier dans un fichier html et d’essayer de coller (en utilisant ctrl-v) du texte du presse-papiers n’importe où sur le document.
Je l'ai testé dans IE9 et dans les nouvelles versions de Firefox, Chrome et Opera. Fonctionne assez bien. En outre, il est bon que vous puissiez utiliser la combinaison de touches de votre choix pour activer cette fonctionnalité. Bien sûr, n'oubliez pas d'inclure les sources jQuery.
N'hésitez pas à utiliser ce code et si vous avez des améliorations ou des problèmes, merci de les poster. Notez également que je ne suis pas un développeur Javascript, donc j'ai peut-être oublié quelque chose (=> faites votre propre test).
Basé sur l2aelba réponse. Cela a été testé sur FF, Safari, Chrome, IE (8,9,10 et 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);
}
}
});
Celui-ci n'utilise aucun setTimeout ().
J'ai utilisé this excellent article pour obtenir une prise en charge multi-navigateurs.
$(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);
}
});
Ce code est étendu avec une poignée de sélection avant coller: démo
Cela devrait fonctionner sur tous les navigateurs prenant en charge l'événement onpaste et l'observateur de mutation.
Cette solution va au-delà du texte uniquement. Elle vous permet en réalité de modifier le contenu collé avant qu'il ne soit collé dans un élément.
Il fonctionne en utilisant des observateurs de mutation (pris en charge par Chrome, Firefox et IE11 +) contenteditable, onpaste (pris en charge par tous les principaux navigateurs) et en mutation.
étape 1
Créer un élément HTML avec contenteditable
<div contenteditable="true" id="target_paste_element"></div>
étape 2
Dans votre code Javascript, ajoutez l'événement suivant
document.getElementById("target_paste_element").addEventListener("paste", pasteEventVerifierEditor.bind(window, pasteCallBack), false);
Nous devons lier pasteCallBack, car l'observateur de mutation sera appelé de manière asynchrone.
étape 3
Ajoutez la fonction suivante à votre code
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();
}
}
}
Que fait le code:
Merci beaucoup à Tim Down Voir ce post pour la réponse:
Récupère le contenu collé sur le document lors de l’événement coller
Pour nettoyer le texte collé et remplacer le texte actuellement sélectionné par le texte collé, le sujet est plutôt trivial:
<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();
}
C'était trop long pour un commentaire sur la réponse de Nico, qui, à mon avis, ne fonctionne plus sous Firefox (d'après les commentaires), et ne fonctionne pas pour moi sous Safari en l'état.
Premièrement, vous semblez maintenant pouvoir lire directement à partir du presse-papiers. Plutôt que de coder comme:
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');
}
utilisation:
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');
}
parce que Firefox a un champ types
qui est un DOMStringList
qui n'implémente pas test
.
Next Firefox n'autorisera pas le collage sauf si le champ _ est utilisé dans le champ contenteditable=true
.
Enfin, Firefox n'autorisera pas le collage de manière fiable à moins que le focus soit dans un textarea
(ou peut-être une entrée) qui n'est pas seulement contenteditable=true
mais aussi:
display:none
visibility:hidden
J'essayais de masquer le champ de texte pour pouvoir utiliser la fonction de collage sur un émulateur JS VNC (c'est-à-dire qu'il était dirigé vers un client distant et qu'il n'y avait pas réellement textarea
etc dans lequel coller). J'ai trouvé que tenter de masquer le champ de texte ci-dessus donnait des symptômes là où cela fonctionnait parfois, mais échouait généralement lors du second collage (ou lorsque le champ était effacé pour éviter de coller deux fois les mêmes données) car le champ avait perdu le focus et ne récupérait pas correctement. malgré focus()
. La solution que j’ai proposée consistait à le placer dans z-order: -1000
, à le transformer en display:none
, à le définir sous la forme 1px sur 1px et à définir toutes les couleurs en transparent. Beurk.
Sur Safari, la deuxième partie de ce qui précède s’applique, c’est-à-dire que vous devez avoir un textarea
qui n’est pas display:none
.
La solution qui fonctionne pour moi consiste à ajouter un écouteur d’événement pour coller un événement si vous le collez dans une entrée de texte. Etant donné que l'événement paste survient avant que le texte en entrée ne change, dans mon gestionnaire on paste, je crée une fonction différée dans laquelle je vérifie les modifications apportées à ma zone de saisie lors de l'insertion:
onPaste: function() {
var oThis = this;
setTimeout(function() { // Defer until onPaste() is done
console.log('paste', oThis.input.value);
// Manipulate pasted input
}, 1);
}
La première chose qui me vient à l’esprit est le gestionnaire de collage de la bibliothèque de fermeture de Google http://closure-library.googlecode.com/svn/trunk/closure/goosure/demos/pastehandler.html
Solution simple:
document.onpaste = function(e) {
var pasted = e.clipboardData.getData('Text');
console.log(pasted)
}
Cette solution est de remplacer la balise html, c'est simple et multi-navigateur; vérifier ce jsfiddle: http://jsfiddle.net/tomwan/cbp1u2cx/1/ , code de base:
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, '');
}
remarque: vous devriez travailler sur le filtre xss au verso car cette solution ne peut pas filtrer les chaînes telles que '<< >>'
Cela a fonctionné pour moi:
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);" />
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;
Vous pouvez le faire de cette façon:
utilisez ce plugin jQuery pour les événements pré et post-collage:
$.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);
});
});
};
Maintenant vous pouvez utiliser ce plugin ;:
$('#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();
Explication
Définissez d'abord un uid pour tous les éléments existants en tant qu'attribut de données.
Comparez ensuite tous les nœuds POST événement PASTE. Donc, en comparant, vous pouvez identifier le nouvel élément inséré, car ils auront un ID utilisateur, puis supprimez simplement l'attribut style/class/id des éléments nouvellement créés, afin que vous puissiez conserver votre ancienne mise en forme.
$('#dom').on('paste',function (e){
setTimeout(function(){
console.log(e.currentTarget.value);
},0);
});
Il suffit de laisser le navigateur coller comme d'habitude dans son contenu éditable, puis, après le collage, permutez les éléments span utilisés pour les styles de texte personnalisés avec le texte lui-même. Cela semble fonctionner correctement dans Internet Explorer et les autres navigateurs que j'ai essayés ...
$('[contenteditable]').on('paste', function (e) {
setTimeout(function () {
$(e.target).children('span').each(function () {
$(this).replaceWith($(this).text());
});
}, 0);
});
Cette solution suppose que vous exécutez jQuery et que vous ne voulez pas formater le texte dans vos divs éditables avec le conten.
Le côté positif est que c'est super simple.
Ceci est un code existant posté ci-dessus mais je l'ai mis à jour pour IE, le bogue qui se passait lorsque le texte existant est sélectionné et que le texte collé ne supprime pas le contenu sélectionné. Ceci a été corrigé par le code ci-dessous
selRange.deleteContents();
Voir le code complet ci-dessous
$('[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);
}
});