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 getData
Funktion 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 onpaste
Ereignis von div
ist die handlePaste
Funktion zugeordnet, und es wurde ein einziges Argument übergeben: das event
Objekt für das Einfügeereignis. Von besonderem Interesse für uns ist die clipboardData
Eigenschaft 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 handlepaste
Funktion:
Diese Funktion hat zwei Zweige.
Der erste prüft auf das Vorhandensein von event.clipboardData
und prüft, ob seine types
Eigenschaft 'text / html' enthält ( types
entweder eine, DOMStringList
die mit der contains
Methode überprüft wird, oder eine Zeichenfolge, die mit der indexOf
Methode ü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
waitForPastedData
Funktion auf
Die waitforpastedata
Funktion:
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 processpaste
Funktion:
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