139 votes

Astuce Javascript pour "coller en texte brut" dans execCommand

J'ai un éditeur de base basé sur execCommand en suivant l'exemple présenté ici. Il y a trois façons de coller du texte dans la fenêtre execCommand zone :

  • Ctrl + V
  • Clic droit -> Coller
  • Clic droit -> Coller en tant que texte brut

Je veux permettre de coller uniquement du texte brut sans aucun balisage HTML. Comment puis-je forcer les deux premières actions à coller du texte brut ?

Solution possible : Le moyen auquel je pense est de définir un écouteur pour les événements de frappe pour ( Ctrl + V ) et supprimer les balises HTML avant de les coller.

  1. Est-ce la meilleure solution ?
  2. Est-il possible d'éviter tout balisage HTML dans le collage ?
  3. Comment ajouter un écouteur au clic droit -> Coller ?

301voto

pimvdb Points 66332

Il interceptera le paste annuler l'événement paste et insérez manuellement la représentation textuelle du presse-papiers :
http://jsfiddle.net/HBEzc/ . Cela devrait être le plus fiable :

  • Il attrape toutes sortes de collages ( Ctrl + V menu contextuel, etc.)
  • Il vous permet d'obtenir les données du presse-papiers directement sous forme de texte, ce qui vous évite d'avoir à faire de vilains bidouillages pour remplacer le HTML.

Je ne suis pas sûr de la compatibilité avec les autres navigateurs, cependant.

editor.addEventListener("paste", function(e) {
    // cancel paste
    e.preventDefault();

    // get text representation of clipboard
    var text = (e.originalEvent || e).clipboardData.getData('text/plain');

    // insert text manually
    document.execCommand("insertHTML", false, text);
});

49voto

Jamie Barker Points 610

Je n'ai pas réussi à faire fonctionner la réponse acceptée ici dans IE, alors j'ai fait quelques recherches et j'ai trouvé cette réponse qui fonctionne dans IE11 et les dernières versions de Chrome et Firefox.

$('[contenteditable]').on('paste', function(e) {
    e.preventDefault();
    var text = '';
    if (e.clipboardData || e.originalEvent.clipboardData) {
      text = (e.originalEvent || e).clipboardData.getData('text/plain');
    } else if (window.clipboardData) {
      text = window.clipboardData.getData('Text');
    }
    if (document.queryCommandSupported('insertText')) {
      document.execCommand('insertText', false, text);
    } else {
      document.execCommand('paste', false, text);
    }
});

23voto

Une solution proche de pimvdb. Mais elle fonctionne sous FF, Chrome et IE 9 :

editor.addEventListener("paste", function(e) {
    e.preventDefault();

    if (e.clipboardData) {
        content = (e.originalEvent || e).clipboardData.getData('text/plain');

        document.execCommand('insertText', false, content);
    }
    else if (window.clipboardData) {
        content = window.clipboardData.getData('Text');

        document.selection.createRange().pasteHTML(content);
    }   
});

19voto

webprogrammer Points 173

Bien sûr, la question a déjà reçu une réponse et le sujet est très ancien, mais je veux fournir ma solution car elle est simple et propre :

C'est dans mon paste-event sur mon contenteditable-div.

var text = '';
var that = $(this);

if (e.clipboardData)
    text = e.clipboardData.getData('text/plain');
else if (window.clipboardData)
    text = window.clipboardData.getData('Text');
else if (e.originalEvent.clipboardData)
    text = $('<div></div>').text(e.originalEvent.clipboardData.getData('text'));

if (document.queryCommandSupported('insertText')) {
    document.execCommand('insertHTML', false, $(text).html());
    return false;
}
else { // IE > 7
    that.find('*').each(function () {
         $(this).addClass('within');
    });

    setTimeout(function () {
          // nochmal alle durchlaufen
          that.find('*').each(function () {
               // wenn das element keine klasse 'within' hat, dann unwrap
               // http://api.jquery.com/unwrap/
               $(this).not('.within').contents().unwrap();
          });
    }, 1);
}

L'autre partie provient d'un autre post de l'OS que je n'ai plus trouvé...


MISE À JOUR 19.11.2014 : L'autre poste SO

9voto

dpr Points 4084

Aucune des réponses affichées ne semble vraiment fonctionner sur plusieurs navigateurs ou la solution est trop compliquée :

  • La commande insertText n'est pas pris en charge par IE
  • Utilisation de la paste entraîne une erreur de dépassement de pile dans IE11

Ce qui a fonctionné pour moi (IE11, Edge, Chrome et FF) est le suivant :

$("div[contenteditable=true]").off('paste').on('paste', function(e) {
    e.preventDefault();
    var text = e.originalEvent.clipboardData ? e.originalEvent.clipboardData.getData('text/plain') : window.clipboardData.getData('Text');
    _insertText(text);
});

function _insertText(text) { 
    // use insertText command if supported
    if (document.queryCommandSupported('insertText')) {
        document.execCommand('insertText', false, text);
    }
    // or insert the text content at the caret's current position
    // replacing eventually selected content
    else {
        var range = document.getSelection().getRangeAt(0);
        range.deleteContents();
        var textNode = document.createTextNode(text);
        range.insertNode(textNode);
        range.selectNodeContents(textNode);
        range.collapse(false);

        var selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
    }
};

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<textarea name="t1"></textarea>
<div style="border: 1px solid;" contenteditable="true">Edit me!</div>
<input />
</body>

Notez que le gestionnaire de collage personnalisé n'est nécessaire/ne fonctionne que dans le cas de contenteditable des nœuds. Comme les deux textarea et simple input ne permettent pas du tout de coller du contenu HTML, il n'y a donc rien à faire ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X