捕获粘贴输入

219

我正在寻找一种方法来对我在浏览器中粘贴的输入进行消毒处理,使用jQuery能实现吗?

到目前为止,我已经想出了以下内容:

$(this).live(pasteEventName, function(e) {
 // this is where i would like to sanitize my input
 return false;
}

很不幸,我的开发因为这个“小”问题而陷入了僵局。如果有人能指点我正确的方向,我会非常高兴。


6
请将 https://dev59.com/-3RB5IYBdhLWcg3wN08P#1503425 标记为解决方案,以帮助其他遇到相同问题的人。这个方法对我很有效。 - saji89
2
.live() 已经在 jQuery 1.9 中被弃用,他们建议使用 .on() 代替。 - Sameer Alibhai
https://dev59.com/RXI95IYBdhLWcg3wvgl9#19269040 - Rajat Gupta
17个回答

349

好的,我也遇到了同样的问题...我绕了一个大弯

$('input').on('paste', function () {
  var element = this;
  setTimeout(function () {
    var text = $(element).val();
    // do something with text
  }, 100);
});

只需要一个小的超时等待,直到.val()函数能够被填充。

E.


21
如果文本框中已经有文本,而你想粘贴的只是你刚复制的文本,该怎么办? - barfoon
42
非常好,谢谢。将超时设置为0同样有效。该函数只需延迟到下一次循环即可。 - Daniel Lewis
5
刚刚遇到了类似的情况。超时是因为粘贴事件不是立即发生的,而是需要几毫秒才能将剪贴板内容粘贴进去。 - James
8
请注意,在 HTML5 中,官方最小超时时间为4毫秒。 - pimvdb
4
像Sharif所说,0毫秒仍然将事件放在堆栈底部。 - BobRodes
显示剩余8条评论

80

您实际上可以直接从事件中获取该值。不过如何获取它有点晦涩。

如果您不想让它传递,请返回false。

$(this).on('paste', function(e) {

  var pasteData = e.originalEvent.clipboardData.getData('text')

});

2
这是正确的方式。 - DdW
1
ie 11: window.clipboardData.getData('text') ie11:window.clipboardData.getData('text') - Wallstrider
6
请注意,只有在使用jQuery处理事件时才需要“originalEvent”属性。在纯JavaScript中,您可以只使用 e.clipboardData.getData('text') - Asier Paz
最佳答案在这里!但是我发现奇怪的是,绑定的简写版本在这里不起作用,即使对于简化的.on('click')也是如此。如果尝试 $(this).paste(function(e) {...}),会报错。 - HoldOffHunger
小问题:代码缺少一个关闭括号。显然,更改太小,不能作为编辑修复它。 - Joachim Lous

46

为了跨平台兼容性,它应该处理oninput和onpropertychange事件:

$ (something).bind ("input propertychange", function (e) {
    // check for paste as in example above and
    // do something
})

2
优美的解决方案,既可以作为粘贴事件,也可以作为按键事件捕获。 注意:如果您在至少IE8中突出显示输入内容,然后再键入某些内容,则此操作会导致事件函数触发两次(在许多情况下不重要,但在其他情况下可能非常重要)。 - baacke
太好了!我不知道这个,而且它完美地满足了我的需求! - Marc Brillault

19

我用以下代码解决了问题:

$("#editor").live('input paste',function(e){
    if(e.target.id == 'editor') {
        $('<textarea></textarea>').attr('id', 'paste').appendTo('#editMode');
        $("#paste").focus();
        setTimeout($(this).paste, 250);
    }
});

现在我只需要存储插入符位置,然后在该位置追加文本即可,这样我就完成了……我想是这样的 :)


1
你是如何存储插入符位置的? - Petah
@Petah 你可以使用.find(':focus')来检查哪个元素具有焦点,并确定其光标位置。参见这里 - Jacob
请记住,“live”已被“on”所取代,不再使用。 - NBPalomino
“input” 很重要 :) 我通常在文本框事件中使用这些:keyup keydown paste input,但显然这取决于你的动机是什么。 - Pierre

10

嗯...我认为你可以使用e.clipboardData来获取粘贴的数据。如果不行,可以在这里查看

$(this).live("paste", function(e) {
    alert(e.clipboardData); // [object Clipboard]
});

2
当我在Safari中运行此代码时,我得到了“undefined”:( - Christoffer Winterkvist
1
clipboardData 在大多数浏览器中都被沙箱化了(这是一个明显的安全漏洞)。 - podperson
2
仅限于Internet Explorer! - Lodewijk

9

监听粘贴事件并设置一个键盘弹起事件的监听器。在键盘弹起时,捕获值并移除键盘弹起事件监听器。

$('.inputTextArea').bind('paste', function (e){
    $(e.target).keyup(getInput);
});
function getInput(e){
    var inputText = $(e.target).val();
    $(e.target).unbind('keyup');
}

6
非常好,但无法在右键粘贴时使用。 - Joseph Ravenwolfe
它不能用于中间点击粘贴(X11),只有当他们使用键盘粘贴时才有效。 - Jasen

7
$("#textboxid").on('input propertychange', function () {
    //perform operation
        });

它将正常工作。


6

这已经更接近你想要的了。

function sanitize(s) {
  return s.replace(/\bfoo\b/g, "~"); 
};

$(function() {
 $(":text, textarea").bind("input paste", function(e) {
   try {
     clipboardData.setData("text",
       sanitize(clipboardData.getData("text"))
     );
   } catch (e) {
     $(this).val( sanitize( $(this).val() ) );
   }
 });
});

请注意,当在IE以外的浏览器上找不到clipboardData对象时,您将获得元素的完整值和剪贴板中的值。
如果您只想知道真正粘贴到元素中的数据,您可以在输入之前和输入之后对这两个值进行一些额外的步骤来区分它们。

6
 $('').bind('input propertychange', function() {....});                      

这将适用于鼠标粘贴事件。


2
这是最佳用法。 - Sinan Eldem

5
比较字段的原始值和更改后的值,并将差异作为粘贴的值减去,这样即使字段中存在现有文本,也可以正确捕获粘贴的文本。 http://jsfiddle.net/6b7sK/
function text_diff(first, second) {
    var start = 0;
    while (start < first.length && first[start] == second[start]) {
        ++start;
    }
    var end = 0;
    while (first.length - end > start && first[first.length - end - 1] == second[second.length - end - 1]) {
        ++end;
    }
    end = second.length - end;
    return second.substr(start, end - start);
}
$('textarea').bind('paste', function () {
    var self = $(this);
    var orig = self.val();
    setTimeout(function () {
        var pasted = text_diff(orig, $(self).val());
        console.log(pasted);
    });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接