JavaScript obtenir des données de bloc-notes sur Coller l'événement (Cross browser)

comment une application web peut-elle détecter un événement de coller et récupérer les données à coller?

je voudrais supprimer le contenu HTML avant que le texte soit collé dans un éditeur de texte riche.

nettoyer le texte après avoir été collé fonctionne, mais le problème est que tout formatage antérieur est perdu. Par exemple, je peux écrire une phrase dans l'éditeur et la mettre en gras, mais quand je colle un nouveau texte, tout le formatage est perdu. Je veux juste le nettoyer texte qui est collé, et laisser tout formatage précédent intact.

idéalement, la solution devrait fonctionner sur tous les navigateurs modernes (par exemple, MSIE, Gecko, Chrome et Safari).

notez que MSIE a clipboardData.getData() , mais je n'ai pas pu trouver de fonctionnalité similaire pour les autres navigateurs.

255
demandé sur Alex 2010-02-01 16:17:25

20 réponses

la situation a changé depuis la rédaction de cette réponse: Maintenant que Firefox a ajouté le support dans la version 22, tous les navigateurs principaux prennent maintenant en charge l'accès aux données du presse-papiers dans un événement de coller. Voir réponse de Nico Burns pour un exemple.

dans le passé, cela n'était généralement pas possible par navigateur. L'idéal serait de pouvoir obtenir le contenu collé via l'événement paste , qui est possible dans les navigateurs récents , mais pas dans certains navigateurs plus anciens (en particulier, Firefox < 22).

lorsque vous avez besoin de prendre en charge des navigateurs plus anciens, ce que vous pouvez faire est tout à fait impliqué et un peu d'un piratage qui fonctionnera dans Firefox 2+, i.e. 5.5+ et les navigateurs WebKit tels que Safari ou Chrome. Les versions récentes de TinyMCE et CKEditor utilisent cette technique:

  1. Détecter un ctrl-v / maj-ins d'événement à l'aide d'un gestionnaire d'événements keypress
  2. dans ce gestionnaire, sauvegardez la sélection de l'utilisateur courant, ajoutez un élément textarea hors-écran (disons à gauche-1000px) au document, tournez designMode off et appelez focus() sur le textarea, déplaçant ainsi le caret et redirigeant efficacement la pâte
  3. fixe une minuterie très courte (disons 1 milliseconde) dans le gestionnaire d'événement pour appeler une autre fonction qui stocke la valeur textarea, supprime la textarea du document, tourne designMode de retour, restaure l'utilisateur sélection et colle le texte en.

notez que cela ne fonctionnera que pour les évènements de paste clavier et non pas pour les paste du contexte ou les menus d'édition. Au moment où l'événement paste se déclenche, il est trop tard pour rediriger le caret dans la textarea (dans certains navigateurs, au moins).

dans le cas peu probable que vous devez supporter Firefox 2, notez que vous aurez besoin de placer le textarea dans le document parent plutôt que le WYSIWYG editor iframe document dans ce navigateur.

133
répondu Tim Down 2017-05-23 12:10:54

Solution #1 (texte clair seulement et nécessite Firefox 22+)

Works for IE6+, FF 22+, Chrome, Safari, Edge (Testé seulement en IE9+, mais devrait fonctionner pour les versions inférieures)

si vous avez besoin de support pour coller HTML ou Firefox <= 22, voir la Solution #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/

notez que cette solution utilise le paramètre 'Text' pour la fonction getData , qui n'est pas standard. Cependant, il fonctionne dans tous les navigateurs au moment de la rédaction.


Solution #2 (HTML et works for Firefox <= 22)

testé en 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'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 /

explication

l'événement onpaste de l'événement div a la fonction handlePaste attachée à lui et a passé un seul argument: l'objet event pour l'événement de pâte. Nous sommes particulièrement intéressés par la propriété clipboardData de cet événement qui permet l'accès au bloc-notes dans les navigateurs non-ie. Dans IE l'équivalent est window.clipboardData , bien que cela ait une API légèrement différente.

voir la section Ressources ci-dessous.


la fonction handlepaste :

cette fonction a deux branches.

les premières vérifications de l'existence de event.clipboardData et vérifie si la propriété types contient "text / html" ( types peut être soit un DOMStringList qui est vérifié en utilisant la méthode contains , ou une chaîne qui est vérifiée en utilisant la méthode indexOf ). Si toutes ces conditions sont remplies, nous procédons comme dans la solution #1, sauf avec 'text/html' au lieu de 'text/plain'. Cela fonctionne actuellement dans Chrome et Firefox 22+.

si cette méthode n'est pas prise en charge (tous les autres navigateurs), alors nous

  1. Enregistrer l'élément est contenu dans un DocumentFragment
  2. vider le élément
  3. appeler la waitForPastedData fonction

la fonction waitforpastedata :

cette fonction interroge d'abord les données collées (une fois par 20ms), ce qui est nécessaire car elle n'apparaît pas tout de suite. Lorsque les données sont apparues:

  1. sauve l'innerHTML de la div modifiable (qui est maintenant les données collées) à un variable
  2. rétablit le contenu enregistré dans le DocumentFragment
  3. appelle la fonction 'processPaste' avec les données récupérées

la fonction processpaste :

fait des choses arbitraires avec les données collées. Dans ce cas, on a juste alerter les données, vous pouvez faire ce que vous voulez. Vous voudrez probablement exécuter les données collées à travers une sorte de processus d'assainissement des données.


sauvegarde et restauration de la position du curseur

dans une situation réelle, vous voudrez probablement sauvegarder la sélection avant, et la restaurer après ( placer la position du curseur sur contentEditable

). Vous pouvez alors insérer les données collées à la position où se trouvait le curseur lorsque l'Utilisateur a lancé l'action paste.

ressources:

Grâce à Tim vers ce qui suggère l'utilisation d'un DocumentFragment, et abligh pour rattraper une erreur dans Firefox en raison de l'utilisation de DOMStringList au lieu d'une chaîne de clipboardData.types

266
répondu Nico Burns 2017-05-23 11:47:36

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);
});

utilisant clipboardData

Démo : http://jsbin.com/nozifexasu/edit?js,sortie

Bord, Firefox, Chrome, Safari, Opera testé.


Note: N'oubliez pas de vérifier l'entrée/sortie à côté serveur aussi (comme PHP bande-tags )

108
répondu l2aelba 2018-09-14 20:40:48

Live Demo

testé sur Chrome / FF /IE11

il y a une gêne Chrome/IE qui est que ces navigateurs ajouter <div> élément pour chaque nouvelle ligne. Il y a un post à propos de ce ici et il peut être fixé en mettant le contenteditable élément à être display:inline-block

sélectionnez quelques HTML surlignés et coller ici:

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>
24
répondu vsync 2017-10-21 10:13:35

j'ai écrit une petite validation de principe pour la proposition de Tim Downs ici avec du texte off-screen. 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-coller le code entier dans un fichier html et d'essayer de coller (en utilisant ctrl-v) le texte à partir de presse-papiers n'importe où sur le document.

Je l'ai testé dans IE9 et les nouvelles versions de Firefox, Chrome et Opera. Fonctionne très bien. Il est également bon que l'on peut utiliser n'importe quelle combinaison de clés qu'il préfère Trigger cette fonctionnalité. Bien sûr, n'oubliez pas d'inclure les sources jQuery.

n'hésitez pas à utiliser ce code et si vous venez avec certaines améliorations ou des problèmes, veuillez les envoyer. Notez aussi que je ne suis pas un développeur Javascript, donc j'ai peut-être manqué quelque chose (=>faire votre propre testign).

15
répondu JanM 2012-05-11 12:30:13

Basé sur l2aelba réponse. Ceci 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);
            }
        }
    });
10
répondu tmorell 2014-01-09 05:44:56

celui-ci n'utilise pas de setTimeout().

j'ai utilisé ce grand article pour obtenir la prise en charge de cross browser.

$(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 la poignée de sélection avant de coller: démo

9
répondu AsgarAli Khanusiya 2017-03-07 09:05:23

pour nettoyer les textes collés et remplacer le texte actuellement sélectionné par le texte collé la matière est assez triviale:

<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();
}
5
répondu Matt Crinklaw-Vogt 2013-10-08 17:06:39

cela devrait fonctionner sur tous les navigateurs qui prennent en charge l'événement onpaste et l'observateur de mutation.

cette solution va au-delà de l'obtention du texte seulement, elle vous permet en fait d'éditer le contenu collé avant qu'il ne soit collé dans un élément.

il fonctionne en utilisant contenteditable, onpaste événement (pris en charge par tous les principaux navigateurs) en mutation observateurs (pris en charge par Chrome, Firefox et IE11+)

é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 avons besoin de se lier à l'arrière, puisque l'observateur de mutation sera appelé asynchrone.

étape 3

ajouter 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();
    }
}

}

Ce que fait le code:

  1. Quelqu'un déclenche l'événement paste en utilisant ctrl-v, contextmenu ou d'autres moyens
  2. dans le cas de pâte un nouvel élément avec contenteditable est créé (un élément avec contenteditable a des privilèges élevés)
  3. la position caret de l'élément cible est sauvegardée.
  4. l'accent est mis sur le nouveau élément
  5. le contenu est collé dans le nouvel élément et est rendu dans le DOM.
  6. l'observateur de mutation saisit ceci (il enregistre tous les changements à l'arbre dom et le contenu). Puis déclenche l'événement de mutation.
  7. le dom du contenu collé est cloné dans une variable et retourné au callback. L'élément temporaire est détruit.
  8. le callback reçoit le DOM cloné. Le signe est restaurer. Vous pouvez le modifier avant de l'ajouter à votre cible. élément. Dans cet exemple, J'utilise les fonctions Tim Downs pour sauvegarder/restaurer le caret et coller HTML dans l'élément.

Merci beaucoup à Tim Down Voir ce billet pour la réponse:

Obtenir le contenu collé sur le document sur la pâte événement

5
répondu Mouser 2017-05-23 11:33:26

la Solution qui fonctionne pour moi est d'ajouter event listener pour coller event si vous collez à une entrée de texte. Puisque l'événement paste se produit avant que le texte dans les modifications d'entrée, à l'intérieur de mon handler on paste je crée une fonction différée à l'intérieur de laquelle je vérifie les changements dans ma boîte d'entrée qui se sont produits sur paste:

onPaste: function() {
    var oThis = this;
    setTimeout(function() { // Defer until onPaste() is done
        console.log('paste', oThis.input.value);
        // Manipulate pasted input
    }, 1);
}
4
répondu Lex 2014-01-13 06:24:09

cela a été trop long pour un commentaire sur la réponse de Nico, qui je ne pense pas fonctionne sur Firefox plus (selon les commentaires), et n'a pas fonctionné pour moi sur Safari comme tel.

tout d'abord, vous semblez maintenant être en mesure de lire directement à partir du bloc-notes. Plutôt que le code 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');
}

utiliser:

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 ne met pas en œuvre test .

Next Firefox ne permettra pas la pâte à moins que le focus soit dans un champ contenteditable=true .

enfin, Firefox ne permettra pas la pâte de manière fiable à moins que le focus ne soit dans un textarea (ou peut-être en entrée) qui est non seulement contenteditable=true mais aussi:

  • pas display:none
  • pas visibility:hidden
  • non zero sized

j'essayais de cacher le champ de texte pour pouvoir faire fonctionner la pâte sur un émulateur JS VNC (c'est-à-dire qu'il allait vers un client distant et qu'il n'y avait pas réellement de textarea etc dans lequel coller). J'ai trouvé en essayant de cacher le champ de texte dans le ci-dessus a donné des symptômes où il a fonctionné parfois, mais typiquement échoué sur la deuxième pâte (ou lorsque le champ a été nettoyé pour empêcher le collage des mêmes données deux fois) que le champ a perdu la mise au point et ne serait pas correctement le retrouver malgré focus() . La solution que j'ai a été de la mettre à z-order: -1000 , faire display:none , faire comme 1px par 1px, et de définir toutes les couleurs transparentes. Beurk.

sur Safari, vous la deuxième partie de ce qui précède s'applique, i.e. vous devez avoir un textarea qui n'est pas display:none .

4
répondu abligh 2015-07-08 07:48:44

le premier qui vient à l'esprit est le pastehandler de la fermeture de google lib http://closure-library.googlecode.com/svn/trunk/closure/goog/demos/pastehandler.html

3
répondu tDo 2010-02-01 13:24:19

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);" />
3
répondu Timmy Duncan 2011-11-13 17:23:26

cette solution remplace la balise html, c'est simple et cross-browser; cochez cette case 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 faire un peu de travail sur le filtre xss sur le dos parce que cette solution ne peut pas filtrer les chaînes comme '< < > > '

2
répondu TomWan 2015-01-20 07:54:56

Vous pouvez le faire de cette façon:

utilisez ce plugin jQuery pour pré & post paste events:

$.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

commence par définir un uid pour tous les éléments existants en tant qu'attribut de données.

puis comparez tous les noeuds post PASTE event. Donc en comparant vous pouvez identifier le nouveau inséré parce que ils auront un uid, puis juste supprimer l'attribut style / class / id des éléments nouvellement créés, de sorte que vous pouvez garder votre formatage plus ancien.

1
répondu Peeyush 2013-11-18 19:26:28
$('#dom').on('paste',function (e){
    setTimeout(function(){
        console.log(e.currentTarget.value);
    },0);
});
1
répondu Roman Yudin 2014-03-19 09:26:28

il suffit de laisser le navigateur coller comme d'habitude dans son contenu editable div Et puis après la pâte d'échanger tous les éléments de portée utilisés pour les styles de texte personnalisés avec le texte lui-même. Cela semble fonctionner bien dans internet explorer et les autres navigateurs que j'ai essayé...

$('[contenteditable]').on('paste', function (e) {
    setTimeout(function () {
        $(e.target).children('span').each(function () {
            $(this).replaceWith($(this).text());
        });
    }, 0);
});

cette solution suppose que vous lancez jQuery et que vous ne voulez pas de formatage de texte dans l'un de vos contenus modifiables divs .

le côté positif est que c'est super simple.

1
répondu DaveAlger 2014-12-27 01:16:54
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;
1
répondu Ivan 2015-05-11 18:28:37

solution Simple:

document.onpaste = function(e) {
    var pasted = e.clipboardData.getData('Text');
    console.log(pasted)
}
1
répondu lama12345 2017-12-30 08:47:55

c'est un code existant posté ci-dessus mais je l'ai mis à jour pour IE, le bug était quand le texte existant est sélectionné et collé ne supprimera pas le contenu sélectionné. Ceci a été corrigé par le code ci-dessous

selRange.deleteContents(); 

voir 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);
    }        
});
0
répondu Ravi Selvaraj 2017-09-14 16:06:57