Lösung Nr. 1 (Nur einfacher Text und erfordert Firefox 22+)
Funktioniert für IE6 +, FF 22+, Chrome, Safari, Edge (Nur in IE9 + getestet, sollte aber für niedrigere Versionen funktionieren)
Wenn Sie Unterstützung zum Einfügen von HTML oder Firefox <= 22 benötigen, lesen Sie Lösung 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/
Beachten Sie, dass diese Lösung den Parameter 'Text' für die getDataFunktion verwendet, der nicht dem Standard entspricht. Es funktioniert jedoch zum Zeitpunkt des Schreibens in allen Browsern.
Lösung 2 (HTML und funktioniert für Firefox <= 22)
Getestet in 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/
Erläuterung
Dem onpasteEreignis von divist die handlePasteFunktion zugeordnet, und es wurde ein einziges Argument übergeben: das eventObjekt für das Einfügeereignis. Von besonderem Interesse für uns ist die clipboardDataEigenschaft dieses Ereignisses, die den Zugriff auf die Zwischenablage in nicht-dh Browsern ermöglicht. Im IE ist das Äquivalent window.clipboardData, obwohl dies eine etwas andere API hat.
Siehe Abschnitt Ressourcen unten.
Die handlepasteFunktion:
Diese Funktion hat zwei Zweige.
Der erste prüft auf das Vorhandensein von event.clipboardDataund prüft, ob seine typesEigenschaft 'text / html' enthält ( typesentweder eine, DOMStringListdie mit der containsMethode überprüft wird, oder eine Zeichenfolge, die mit der indexOfMethode überprüft wird). Wenn alle diese Bedingungen erfüllt sind, fahren wir wie in Lösung 1 fort, außer mit 'text / html' anstelle von 'text / plain'. Dies funktioniert derzeit in Chrome und Firefox 22+.
Wenn diese Methode nicht unterstützt wird (alle anderen Browser), dann wir
- Speichern Sie den Inhalt des Elements in a
DocumentFragment
- Leeren Sie das Element
- Rufen Sie die
waitForPastedDataFunktion auf
Die waitforpastedataFunktion:
Diese Funktion fragt zuerst nach den eingefügten Daten (einmal pro 20 ms), was erforderlich ist, da sie nicht sofort angezeigt werden. Wenn die Daten erschienen sind:
- Speichert das innerHTML des bearbeitbaren div (das jetzt die eingefügten Daten sind) in einer Variablen
- Stellt den im DocumentFragment gespeicherten Inhalt wieder her
- Ruft die Funktion 'processPaste' mit den abgerufenen Daten auf
Die processpasteFunktion:
Macht willkürliche Dinge mit den eingefügten Daten. In diesem Fall alarmieren wir nur die Daten, Sie können tun, was Sie wollen. Möglicherweise möchten Sie die eingefügten Daten durch einen Datenbereinigungsprozess ausführen.
Speichern und Wiederherstellen der Cursorposition
In einer realen Situation möchten Sie wahrscheinlich die Auswahl vorher speichern und danach wiederherstellen ( Cursorposition auf contentEditable <div> setzen ). Sie können die eingefügten Daten dann an der Position einfügen, an der sich der Cursor befand, als der Benutzer die Einfügemaßnahme initiierte.
Ressourcen:
Vielen Dank an Tim Down für den Vorschlag, ein DocumentFragment zu verwenden, und für das Abfangen eines Fehlers in Firefox aufgrund der Verwendung von DOMStringList anstelle einer Zeichenfolge für clipboardData.types