我目前有一个文本区域,我需要控制已粘贴的文本,
本质上,我需要能够将用户想要粘贴到文本区域中的任何内容放入变量中。
然后我会计算出他们粘贴文本的位置和字符串的大小以将其从文本区域中删除,
然后最后以我自己的方式处理变量中的文本。
我的问题:我将如何获取用户刚刚粘贴的变量中的文本副本?
谢谢。
我目前有一个文本区域,我需要控制已粘贴的文本,
本质上,我需要能够将用户想要粘贴到文本区域中的任何内容放入变量中。
然后我会计算出他们粘贴文本的位置和字符串的大小以将其从文本区域中删除,
然后最后以我自己的方式处理变量中的文本。
我的问题:我将如何获取用户刚刚粘贴的变量中的文本副本?
谢谢。
前几天我回答了一个类似的问题:Detect paste text with ctrl+v or right click -> paste。这次我包含了一个相当长的函数,可以准确地获取 IE 中 textarea 中的选择边界;剩下的就比较简单了。
您可以使用 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/ )。它可以让您控制将哪些内容粘贴到 textarea 或 contenteditable 中,并且您将能够随意过滤/更改/提取内容。
快速搜索告诉我,不同的浏览器有不同的方法。我不确定 jQuery 是否有解决方案。Prototype.js 似乎没有。也许 YUI 可以为您做到这一点?
您也可以使用 TinyMCE,因为它确实有大量不同的事件触发器。它是一个成熟的文字处理器,但如果需要,您可以将其用作纯文本。不过加起来可能有点过重。例如,在启动时,它会将您<textarea>
变成一个带有多个子的 iFrame。但它会做你所要求的。
——戴夫