Çözüm # 1 (Yalnızca Düz Metin ve Firefox 22+ gerekir)
IE6 +, FF 22+, Chrome, Safari, Edge için çalışır (Yalnızca IE9 + 'da test edilmiştir, ancak daha düşük sürümlerde çalışmalıdır)
HTML veya Firefox <= 22 yapıştırmak için desteğe ihtiyacınız varsa bkz. Çözüm # 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/
Bu çözümün getDatastandart olmayan işlev için 'Metin' parametresini kullandığını unutmayın . Ancak, yazma sırasında tüm tarayıcılarda çalışır.
Çözüm # 2 (HTML ve Firefox <= 22 için çalışır)
IE6 +, FF 3.5+, Chrome, Safari, Edge'de test edildi
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/
açıklama
onpasteOlay divvardır handlePaste: kendisine bağlı ve tek bir argüman geçirilen işlevi eventmacunu etkinlik için nesne. Bizi özellikle ilgilendiren clipboardDatabu olayın özelliği, yani tarayıcı olmayan tarayıcılarda pano erişimine olanak tanır. IE'de eşdeğerwindow.clipboardData bunun biraz farklı bir API'sı olmasına rağmen.
Aşağıdaki kaynaklar bölümüne bakın.
handlepastefonksiyon:
Bu fonksiyonun iki dalı vardır.
İlk olup olmadığını kontrol eder event.clipboardData, bu ister ve kontrol typesniteliği metin / html 'içerir ( typesolabilir ya da bir DOMStringListile kontrol edilir containsyöntem veya kontrol edilir, bir dizi indexOfyöntem). Bu koşulların tümü yerine getirilirse, 'text / plain' yerine 'text / html' dışında # 1 numaralı çözümde olduğu gibi ilerliyoruz. Bu şu anda Chrome ve Firefox 22+ sürümlerinde çalışmaktadır.
Bu yöntem desteklenmiyorsa (diğer tüm tarayıcılar),
- Öğenin içeriğini bir
DocumentFragment
- Elemanı boşaltın
waitForPastedDataİşlevi çağır
waitforpastedatafonksiyon:
Bu işlev önce yapıştırılan veriler için (her 20 ms'de bir) yoklar; bu, hemen görünmediği için gereklidir. Veriler göründüğünde:
- Düzenlenebilir div'in (şimdi yapıştırılan verilerdir) innerHTML'sini bir değişkene kaydeder
- DocumentFragment'a kaydedilen içeriği geri yükler
- Alınan verilerle 'processPaste' işlevini çağırır
processpastefonksiyon:
Yapıştırılan verilerle keyfi şeyler yapar. Bu durumda sadece verileri uyarırız, istediğinizi yapabilirsiniz. Yapıştırılan verileri muhtemelen bir tür veri temizleme işlemi ile çalıştırmak isteyeceksiniz.
İmleç konumunu kaydetme ve geri yükleme
Gerçek bir durumda, muhtemelen daha önce seçimi kaydetmek ve daha sonra geri yüklemek istersiniz ( contentEditable <div> öğesinde imleç konumunu ayarlayın ). Daha sonra yapıştırılan verileri, kullanıcı yapıştırma işlemini başlattığında imlecin bulunduğu konuma ekleyebilirsiniz.
Kaynaklar:
DocumentFragment kullanımını öneren Tim Down'a ve clipboardData.types için dize yerine DOMStringList kullanımı nedeniyle Firefox'ta bir hata yakalamak için abligh'e teşekkürler