javascript捕获文本区域中的粘贴事件

发布于 2024-09-09 06:14:47 字数 198 浏览 4 评论 0原文

我目前有一个文本区域,我需要控制已粘贴的文本,

本质上我需要能够获取用户想要粘贴到文本区域中的任何内容并将其放入变量中。

然后,我将计算出他们粘贴文本的位置和字符串的大小,以将其从文本区域中删除,

然后最后以我自己的方式处理变量中的文本。

我的问题:我将如何获取用户刚刚粘贴的变量中的文本副本?

谢谢。

I currently have a textarea which I requires control over text that has been pasted in,

essentially I need to be able to take whatever the user wants to paste into a textarea and place it into a variable.

I will then work out the position in which they pasted the text and the size of the string to remove it from the textarea,

Then at the end deal with the text thats is in the variable in my own way.

My question: how would I go about getting a copy of the text in a variable that was just pasted in by the user?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

雪落纷纷 2024-09-16 06:14:47

几天前我回答了类似的问题: 使用 ctrl+v 或右键单击检测粘贴的文本 ->粘贴。这次我包含了一个相当长的函数,可以准确地获取 IE 中文本区域的选择边界;剩下的就比较简单了。

您可以使用粘贴事件来检测大多数浏览器中的粘贴(尤其是 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);
    });
};

I answered a similar question a few days ago: Detect pasted text with ctrl+v or right click -> paste. This time I've included quite a long function that accurately gets selection boundaries in textarea in IE; the rest is relatively simple.

You can use the paste event to detect the paste in most browsers (notably not Firefox 2 though). When you handle the paste event, record the current selection, and then set a brief timer that calls a function after the paste has completed. This function can then compare lengths to know where to look for the pasted content. Something like the following:

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);
    });
};
口干舌燥 2024-09-16 06:14:47

You might now use FilteredPaste.js (http://willemmulder.github.com/FilteredPaste.js/) instead. It will let you control what content gets pasted into a textarea or contenteditable and you will be able to filter/change/extract content at will.

樱花细雨 2024-09-16 06:14:47

快速搜索表明,不同的浏览器有不同的方法。我不确定 jQuery 是否有解决方案。 Prototype.js 似乎没有。也许 YUI 可以为你做到这一点?

您还可以使用 TinyMCE,因为它确实有无数不同的事件触发器。它是一个成熟的文字处理器,但如果您愿意,您可以将其用作纯文本。不过,添加的重量可能有点太多了。例如,启动后,它会将您的

——戴夫

A quick search shows me that there are different methods for different browsers. I'm not sure if jQuery has a solution. Prototype.js does not appear to have one. Maybe YUI can do this for you?

You can also use TinyMCE, since it does have a gazillion of different event triggers. It is a full fledged word processor, but you can use it as plain text if you want. It might be a bit too much weight to add though. For example, upon initiation, it turns your <textarea> into an iFrame with several sub. But it will do what you ask.

--Dave

奈何桥上唱咆哮 2024-09-16 06:14:47

关于获取粘贴内容的问题,您可以使用事件的 ClipboardData 属性:

myTextArea.addEventListener("paste", (e) => {
    // Get new paste
    const paste = (e.clipboardData || window.clipboardData).getData("text");

    // Get "old" textarea content (without latest paste)
    const content = e.target.value;
});

Regarding your question on getting the pasted content, you can use the event's clipboardData property:

myTextArea.addEventListener("paste", (e) => {
    // Get new paste
    const paste = (e.clipboardData || window.clipboardData).getData("text");

    // Get "old" textarea content (without latest paste)
    const content = e.target.value;
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文