ここに紹介したサンプルに続いて、execCommand
に基づいた基本的なエディターがあります。 execCommand
エリア内にテキストを貼り付けるには、次の3つの方法があります。
HTMLマークアップなしでプレーンテキストのみを貼り付けたい。最初の2つのアクションでプレーンテキストを貼り付けるにはどうすればよいですか?
可能な解決策:私が考えることができる方法は、(のキーアップイベントのリスナーを設定することですCtrl+V)、貼り付け前にHTMLタグを削除します。
paste
イベントをインターセプトし、paste
をキャンセルし、クリップボードのテキスト表現を手動で挿入します。
http://jsfiddle.net/HBEzc/ 。これが最も信頼できるはずです:
ただし、クロスブラウザのサポートについてはわかりません。
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);
});
ここでIEで動作するために受け入れられた答えを得ることができなかったので、いくつかのスカウトを行い、IE11およびChromeおよび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);
}
});
Pimvdbとしての緊密なソリューション。しかし、FF、Chromeおよび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);
}
});
もちろん、質問はすでに答えられており、トピックは非常に古いですが、簡単できれいなので、私のソリューションを提供したいと思います:
これは、contenteditable-divのpaste-event内にあります。
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);
}
Else-partは、もう見つけることができなかった別のSOポストからのものです...
更新日2014年11月19日: 他のSOポスト
投稿された回答のいずれも、実際にはクロスブラウザーで動作しないようであるか、解決策が複雑すぎます。
insertText
はIEでサポートされていませんpaste
コマンドを使用すると、IE11でスタックオーバーフローエラーが発生します。私のために働いたのは(IE11、Edge、Chrome、FF)次のとおりです:
$("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>
カスタムペーストハンドラは、contenteditable
ノードに対してのみ必要/機能することに注意してください。 textarea
フィールドとプレーンinput
フィールドはどちらもHTMLコンテンツの貼り付けをまったくサポートしていないため、ここで何もする必要はありません。
Firefoxでは、クリップボードのデータにアクセスすることはできません。そのため、クリップボードを機能させるには「ハック」を行う必要があります。完全な解決策を見つけることができませんでしたが、代わりにテキストエリアを作成して貼り付けることで、ctrl + vペーストで修正できます:
//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);
}
また、プレーンテキストペーストの作業を行っていましたが、execCommandとgetDataのエラーをすべて嫌い始めたので、古典的な方法で行うことにしました。
$('#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);
});
私の表記のコードはここにあります: http://www.albertmartin.de/blog/code.php/20/plain-text-paste-with-javascript
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();
}
}
上記のコードはIE10およびIE11で機能し、現在ChromeおよびSafariでも機能します。 Firefoxではテストされていません。
IE11では、execCommandはうまく機能しません。 IE11の以下のコードを使用します<div class="wmd-input" id="wmd-input-md" contenteditable=true>
はdivボックスです。
Window.clipboardDataからクリップボードデータを読み取り、divのtextContentを変更し、キャレットを付けます。
キャレットの設定にタイムアウトを設定します。タイムアウトを設定しないと、キャレットがdivの最後に移動するためです。
iE11でclipboardDataを以下の方法で読む必要があります。そうしないと、改行文字が適切に処理されないため、キャレットが間違ってしまいます。
var tempDiv = document.createElement("div");
tempDiv.textContent = window.clipboardData.getData("text");
var text = tempDiv.textContent;
IE11およびchromeでテスト済み。 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);
探索と試行の後、私は何らかの形で最適なソリューションを見つけました
覚えておくべき重要なこと
// /\x0D/g return key ASCII
window.document.execCommand('insertHTML', false, text.replace('/\x0D/g', "\\n"))
and give the css style white-space: pre-line //for displaying
var contenteditable = document.querySelector('[contenteditable]')
contenteditable.addEventListener('paste', function(e){
let text = ''
contenteditable.classList.remove('empty')
e.preventDefault()
text = (e.originalEvent || e).clipboardData.getData('text/plain')
e.clipboardData.setData('text/plain', '')
window.document.execCommand('insertHTML', false, text.replace('/\x0D/g', "\\n"))// /\x0D/g return ASCII
})
#input{
width: 100%;
height: 100px;
border: 1px solid black;
white-space: pre-line;
}
<div id="input"contenteditable="true">
<p>
</p>
</div>