如何在粘贴事件中捕获输入值?

24

在我的网站上,用户可以将文本(在这种情况下是url)粘贴到输入框中。我想使用jQuery捕获已粘贴文本的值。我已经通过以下代码使其在FF中工作,但它在IE中不起作用(我认为IE不支持“paste”事件)。

有人知道如何在所有现代浏览器中使其正常工作吗?我在SO上找到了几个其他答案,但大多数仅适用于FF,并且没有一个似乎提供完整的解决方案。

以下是我目前拥有的代码:

$("input.url").live('paste', function(event) {
    var _this = this;
    // Short pause to wait for paste to complete
    setTimeout( function() {
        var text = $(_this).val();
        $(".display").html(text);
    }, 100);
});

JSFiddle: http://jsfiddle.net/TZWsB/1/


2
请提供更具体的上下文信息,以便确定需要翻译哪些内容。 - Avien
谢谢 @Avien,哇,那是一些复杂的技巧 :) 不幸的是,阅读这些解决方案后发现没有一个能够完全正确地工作,或者在所有现代浏览器上都能工作。 - rolling stone
这个也许会有帮助,使用jquery并且更简单:https://dev59.com/W3E85IYBdhLWcg3wMAbc - Sitnik
5个回答

30

jQuery在IE浏览器中使用live方法处理粘贴事件会出现问题,可以采用以下解决方案:

$(document).ready(function() {
    $(".url").bind('paste', function(event) {
        var _this = this;
        // Short pause to wait for paste to complete
        setTimeout( function() {
            var text = $(_this).val();
            $(".display").html(text);
        }, 100);
    });
});

Fiddle:http://jsfiddle.net/Trg9F/


+1 感谢 @scessor,这很有帮助。问题在于我让用户动态添加更多的输入,所以我需要实时方法。有没有办法使它与 live 一起工作,而不是通过隐藏输入组合解决方案来进行操作? - rolling stone
我有一个不需要实时操作的解决方案:当您动态添加输入时,可以取消所有带有类别“url”的节点绑定,并重新绑定粘贴事件;虽然不太完美,但很简单。 - scessor
到了2016年,Chrome也有同样的问题。我一直在想我做错了什么,直到我找到了这篇文章。谢谢你的回答,非常有帮助! - Paweł
这个答案同样适用于常规的JavaScript。 - ganjeii

27
$('input').on('paste', function(e) {
    // common browser -> e.originalEvent.clipboardData
    // uncommon browser -> window.clipboardData
    var clipboardData = e.clipboardData || e.originalEvent.clipboardData || window.clipboardData;
    var pastedData = clipboardData.getData('text');
});

在我搜索的所有解决方案中,目前只有这个对我有效。 - palerdot
had to be 'text/plain' for me - Dennis Hackethal

20

除了粘贴 (paste) 事件外,还要监听 change 事件。在提交之前,change 会在更改字段时可靠地触发,而 paste 仅在支持显式粘贴的浏览器上发生;它不会被其他编辑操作(如拖放、剪切复制、撤消重做、拼写检查、IME 替换等)触发。

change 的问题在于它并不会立即触发,只有在编辑字段完成后才会触发。如果你想实时捕获所有更改,你需要使用 input 事件... 但这是一个新的 HTML5 特性,不是每个地方都支持(尤其是:IE<9)。你可以通过捕获所有这些事件来实现几乎相同的效果:

$('.url').bind('input change paste keyup mouseup',function(e){
    ...
});

但如果你想在不支持input的浏览器中确保快速捕获每个更改,那么你别无选择,只能在setInterval上轮询该值。


+1 感谢 @bobince!我应该提到所有用户在这个输入框中所做的(我应该说应该做的)都是粘贴一个URL。另外,看起来我错了,IE确实支持“粘贴”,只是在“实时”和“粘贴”方面存在一些问题。我的问题是,我正在动态生成一些基于他们粘贴的URL的内容,并希望向用户显示以确保在提交之前它是正确的。事实上,当粘贴URL时,我实际上会禁用提交按钮,直到完成所有jQuery函数的操作。任何建议将不胜感激! - rolling stone
是的,在某些情况下,IE中的onpaste不会冒泡,而jQuery的live使用事件委托,需要冒泡。还有其他特定于浏览器的问题,例如在Safari中文本区域中不会触发onpaste。无论兼容性问题如何,我建议允许用户以任何方式填写字段,包括直接输入和拖放,而不是仅针对粘贴操作。 - bobince
谢谢@bobince,我一定会考虑到这个因素。change事件是捕获拖放的最佳事件吗? - rolling stone
@bobince,谢谢,IE8中没有“input”事件。我发现“drop”事件很有用。它在IE8/9/10、Chrome和FF上都可以工作。 - bob

6
更好的方法是使用 e.originalEvent.clipboardData.getData('text'); 来获取粘贴的数据;
$("input").on("paste", function(e) { 
    var pastedData = e.originalEvent.clipboardData.getData('text');
    // ... now do with pastedData whatever you like ...
});

这样你就可以避免超时问题,而且所有主流浏览器都支持这种方式。

我喜欢这个想法,但是对于我来说,e.originalEvent有很多属性,但它没有clipboardData字段/属性:( [FYI我使用Microsoft TypeSafe&JQuery 3.1.1和jQuery UI 1.12.1编写我的Javascript。] - Zeek2

0
也许可以尝试使用onblur事件。这样,用户可以将内容复制/粘贴到输入框中,当他们离开该字段时,脚本会检查其中的内容。这可以节省很多麻烦,因为它适用于鼠标和键盘复制/粘贴以及手动输入的内容。

感谢@qw3n。问题在于页面上只有URL字段,所以我确定会出现用户只粘贴URL并点击提交(而不离开该字段)的情况。 - rolling stone
@rolling stone 好的,你可以做一个双重检查。获取onsubmit事件并检查输入。如果为空返回true,否则返回false。问题是你必须要防止函数运行两次。因为onblur事件仍会触发。或许可以使用一个布尔值切换变量来表示是否已经从一个函数中触发了该事件。希望这样说得清楚。虽然有些复杂,但我认为比其他方法更简单。 - qw3n

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