【问题标题】:javascript catch paste event in textareajavascript在textarea中捕获粘贴事件
【发布时间】:2010-07-13 16:17:38
【问题描述】:

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

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

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

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

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

谢谢。

【问题讨论】:

    标签: javascript events textarea paste


    【解决方案1】:

    几天前我回答了一个类似的问题:Detect pasted 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);
        });
    };
    

    【讨论】:

      【解决方案2】:

      您现在可以改用 FilteredPaste.js (http://willemmulder.github.com/FilteredPaste.js/)。它可以让您控制将哪些内容粘贴到 textarea 或 contenteditable 中,并且您将能够随意过滤/更改/提取内容。

      【讨论】:

        【解决方案3】:

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

        您也可以使用 TinyMCE,因为它确实有大量不同的事件触发器。它是一个成熟的文字处理器,但如果需要,您可以将其用作纯文本。不过加起来可能有点过重。例如,在启动时,它会将您的 <textarea> 变成一个带有多个子的 iFrame。但它会按照你的要求做。

        --戴夫

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多