現在、貼り付けられたテキストを制御する必要があるテキストエリアがあります。
基本的に、ユーザーがテキストエリアに貼り付けたいものを何でも取得して、変数に配置できる必要があります。
次に、テキストを貼り付けた位置と文字列のサイズを計算して、テキスト領域から削除します。
最後に、変数にあるテキストを独自の方法で処理します。
私の質問: ユーザーが貼り付けたばかりの変数内のテキストのコピーを取得するにはどうすればよいですか?
ありがとう。
現在、貼り付けられたテキストを制御する必要があるテキストエリアがあります。
基本的に、ユーザーがテキストエリアに貼り付けたいものを何でも取得して、変数に配置できる必要があります。
次に、テキストを貼り付けた位置と文字列のサイズを計算して、テキスト領域から削除します。
最後に、変数にあるテキストを独自の方法で処理します。
私の質問: ユーザーが貼り付けたばかりの変数内のテキストのコピーを取得するにはどうすればよいですか?
ありがとう。
数日前に同様の質問に答えました: ctrl+v または右クリック -> 貼り付けで貼り付けられたテキストを検出します。今回は、IE のテキストエリアで選択境界を正確に取得するかなり長い関数を含めました。残りは比較的単純です。
Paste イベントを使用して、ほとんどのブラウザーで貼り付けを検出できます (特に Firefox 2 ではそうではありません)。貼り付けイベントを処理するときは、現在の選択内容を記録し、貼り付けの完了後に関数を呼び出す短いタイマーを設定します。この関数は、長さを比較して、貼り付けられたコンテンツを探す場所を知ることができます。次のようなもの:
function getSelectionBoundary(el, start) {
var property = start ? "selectionStart" : "selectionEnd";
var originalValue, textInputRange, precedingRange, pos, bookmark, isAtEnd;
if (typeof el[property] == "number") {
return el[property];
} else if (document.selection && document.selection.createRange) {
el.focus();
var range = document.selection.createRange();
if (range) {
// Collapse the selected range if the selection is not a caret
if (document.selection.type == "Text") {
range.collapse(!!start);
}
originalValue = el.value;
textInputRange = el.createTextRange();
precedingRange = el.createTextRange();
pos = 0;
bookmark = range.getBookmark();
textInputRange.moveToBookmark(bookmark);
if (/[\r\n]/.test(originalValue)) {
// Trickier case where input value contains line breaks
// Test whether the selection range is at the end of the
// text input by moving it on by one character and
// checking if it's still within the text input.
try {
range.move("character", 1);
isAtEnd = (range.parentElement() != el);
} catch (ex) {
log.warn("Error moving range", ex);
isAtEnd = true;
}
range.moveToBookmark(bookmark);
if (isAtEnd) {
pos = originalValue.length;
} else {
// Insert a character in the text input range and use
// that as a marker
textInputRange.text = " ";
precedingRange.setEndPoint("EndToStart", textInputRange);
pos = precedingRange.text.length - 1;
// Delete the inserted character
textInputRange.moveStart("character", -1);
textInputRange.text = "";
}
} else {
// Easier case where input value contains no line breaks
precedingRange.setEndPoint("EndToStart", textInputRange);
pos = precedingRange.text.length;
}
return pos;
}
}
return 0;
}
function getTextAreaSelection(textarea) {
var start = getSelectionBoundary(textarea, true),
end = getSelectionBoundary(textarea, false);
return {
start: start,
end: end,
length: end - start,
text: textarea.value.slice(start, end)
};
}
function detectPaste(textarea, callback) {
textarea.onpaste = function() {
var sel = getTextAreaSelection(textarea);
var initialLength = textarea.value.length;
window.setTimeout(function() {
var val = textarea.value;
var pastedTextLength = val.length - (initialLength - sel.length);
var end = sel.start + pastedTextLength;
callback({
start: sel.start,
end: end,
length: pastedTextLength,
text: val.slice(sel.start, end),
replacedText: sel.text
});
}, 1);
};
}
window.onload = function() {
var textarea = document.getElementById("your_textarea");
detectPaste(textarea, function(pasteInfo) {
var val = textarea.value;
// Delete the pasted text and restore any previously selected text
textarea.value = val.slice(0, pasteInfo.start) +
pasteInfo.replacedText + val.slice(pasteInfo.end);
alert(pasteInfo.text);
});
};
代わりにFilteredPaste.js ( http://willemmulder.github.com/FilteredPaste.js/ ) を使用できます。どのコンテンツをテキストエリアまたは contenteditable に貼り付けるかを制御でき、コンテンツを自由にフィルタリング/変更/抽出できます。
簡単に検索すると、ブラウザごとに異なる方法があることがわかります。jQuery に解決策があるかどうかはわかりません。Prototype.js には存在しないようです。多分YUIはあなたのためにこれをすることができますか?
TinyMCE には無数の異なるイベント トリガーがあるため、TinyMCE を使用することもできます。本格的なワープロですが、必要に応じてプレーンテキストとして使用することもできます。ただし、追加するには少し重すぎるかもしれません。たとえば、開始時に、<textarea>
いくつかのサブを持つ iFrame に変わります。しかし、それはあなたが求めることをします。
--デイブ