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 ?

3voto

MidnightTortoise Points 131

Firefox ne vous permet pas d'accéder aux données du presse-papiers. Vous devrez donc faire un "hack" pour que cela fonctionne. Je n'ai pas été en mesure de trouver une solution complète, mais vous pouvez résoudre le problème des collages par ctrl+v en créant une zone de texte et en y collant à la place :

//Test if browser has the clipboard object
if (!window.Clipboard)
{
    /*Create a text area element to hold your pasted text
    Textarea is a good choice as it will make anything added to it in to plain text*/           
    var paster = document.createElement("textarea");
    //Hide the textarea
    paster.style.display = "none";              
    document.body.appendChild(paster);
    //Add a new keydown event tou your editor
    editor.addEventListener("keydown", function(e){

        function handlePaste()
        {
            //Get the text from the textarea
            var pastedText = paster.value;
            //Move the cursor back to the editor
            editor.focus();
            //Check that there is a value. FF throws an error for insertHTML with an empty string
            if (pastedText !== "") document.execCommand("insertHTML", false, pastedText);
            //Reset the textarea
            paster.value = "";
        }

        if (e.which === 86 && e.ctrlKey)
        {
            //ctrl+v => paste
            //Set the focus on your textarea
            paster.focus();
            //We need to wait a bit, otherwise FF will still try to paste in the editor => settimeout
            window.setTimeout(handlePaste, 1);
        }

    }, false);
}
else //Pretty much the answer given by pimvdb above
{
    //Add listener for paster to force paste-as-plain-text
    editor.addEventListener("paste", function(e){

        //Get the plain text from the clipboard
        var plain = (!!e.clipboardData)? e.clipboardData.getData("text/plain") : window.clipboardData.getData("Text");
            //Stop default paste action
        e.preventDefault();
        //Paste plain text
        document.execCommand("insertHTML", false, plain);

    }, false);
}

2voto

Albert Points 41

Je travaillais également sur un collage de texte brut et j'ai commencé à détester toutes les erreurs execCommand et getData, j'ai donc décidé de le faire de manière classique et cela fonctionne comme un charme :

$('#editor').bind('paste', function(){
    var before = document.getElementById('editor').innerHTML;
    setTimeout(function(){
        var after = document.getElementById('editor').innerHTML;
        var pos1 = -1;
        var pos2 = -1;
        for (var i=0; i<after.length; i++) {
            if (pos1 == -1 && before.substr(i, 1) != after.substr(i, 1)) pos1 = i;
            if (pos2 == -1 && before.substr(before.length-i-1, 1) != after.substr(after.length-i-1, 1)) pos2 = i;
        }
        var pasted = after.substr(pos1, after.length-pos2-pos1);
        var replace = pasted.replace(/<[^>]+>/g, '');
        var replaced = after.substr(0, pos1)+replace+after.substr(pos1+pasted.length);
        document.getElementById('editor').innerHTML = replaced;
    }, 100);
});

Le code avec mes notations peut être trouvé ici : http://www.albertmartin.de/blog/code.php/20/plain-text-paste-with-javascript

2voto

Son Tr. Points 123

En 2022, vous pouvez utiliser le CSS user-modify : read-write-plaintext-only pour archiver ceci

.plain-text-only {
  user-modify: read-write-plaintext-only;
  -moz-user-modify: read-write-plaintext-only;
  -webkit-user-modify: read-write-plaintext-only;
}

div[contenteditable] {
  padding: 1rem 0.5rem;
  border: 2px solid #eee;
  border-radius: 4px;
  margin-bottom: 2rem;
}
<div contenteditable class="plain-text-only">Can't paste HTML here</div>
<div contenteditable>HTML styled text free</div>

1voto

Nikhil Ghuse Points 1075
function PasteString() {
    var editor = document.getElementById("TemplateSubPage");
    editor.focus();
  //  editor.select();
    document.execCommand('Paste');
}

function CopyString() {
    var input = document.getElementById("TemplateSubPage");
    input.focus();
   // input.select();
    document.execCommand('Copy');
    if (document.selection || document.textSelection) {
        document.selection.empty();
    } else if (window.getSelection) {
        window.getSelection().removeAllRanges();
    }
}

Le code ci-dessus fonctionne pour moi dans IE10 et IE11 et maintenant aussi dans Chrome et Safari. Non testé dans Firefox.

1voto

Lee Hojin Points 79

Dans IE11, execCommand ne fonctionne pas bien. J'utilise le code ci-dessous pour IE11 <div class="wmd-input" id="wmd-input-md" contenteditable=true> est ma boîte div.

Je lis les données du presse-papiers à partir de window.clipboardData et je modifie le textContent de la div et donne un signe d'insertion.

Je donne un délai pour la mise en place du caret, parce que si je ne mets pas de délai, le caret va à la fin du div.

et vous devez lire les clipboardData dans IE11 de la manière suivante. Si vous ne le faites pas, le caractère de nouvelle ligne n'est pas traité correctement, et le signe d'insertion est incorrect.

var tempDiv = document.createElement("div");
tempDiv.textContent = window.clipboardData.getData("text");
var text = tempDiv.textContent;

Testé sur IE11 et chrome. Il se peut qu'il ne fonctionne pas sur IE9

document.getElementById("wmd-input-md").addEventListener("paste", function (e) {
    if (!e.clipboardData) {
        //For IE11
        e.preventDefault();
        e.stopPropagation();
        var tempDiv = document.createElement("div");
        tempDiv.textContent = window.clipboardData.getData("text");
        var text = tempDiv.textContent;
        var selection = document.getSelection();
        var start = selection.anchorOffset > selection.focusOffset ? selection.focusOffset : selection.anchorOffset;
        var end = selection.anchorOffset > selection.focusOffset ? selection.anchorOffset : selection.focusOffset;                    
        selection.removeAllRanges();

        setTimeout(function () {    
            $(".wmd-input").text($(".wmd-input").text().substring(0, start)
              + text
              + $(".wmd-input").text().substring(end));
            var range = document.createRange();
            range.setStart(document.getElementsByClassName("wmd-input")[0].firstChild, start + text.length);
            range.setEnd(document.getElementsByClassName("wmd-input")[0].firstChild, start + text.length);

            selection.addRange(range);
        }, 1);
    } else {                
        //For Chrome
        e.preventDefault();
        var text = e.clipboardData.getData("text");

        var selection = document.getSelection();
        var start = selection.anchorOffset > selection.focusOffset ? selection.focusOffset : selection.anchorOffset;
        var end = selection.anchorOffset > selection.focusOffset ? selection.anchorOffset : selection.focusOffset;

        $(this).text($(this).text().substring(0, start)
          + text
          + $(this).text().substring(end));

        var range = document.createRange();
        range.setStart($(this)[0].firstChild, start + text.length);
        range.setEnd($(this)[0].firstChild, start + text.length);
        selection.removeAllRanges();
        selection.addRange(range);
    }
}, false);

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