【问题标题】:Catch paste input捕捉粘贴输入
【发布时间】:2010-10-15 18:41:22
【问题描述】:

我正在寻找一种方法来清理我粘贴到浏览器中的输入,这可能与 jQuery 相关吗?

到目前为止,我已经设法提出了这个建议:

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

不幸的是,由于这个“小”问题,我的发展陷入了困境。 如果有人能指出正确的方向,我真的会让我成为一个快乐的露营者。

【问题讨论】:

标签: jquery paste sanitize


【解决方案1】:

好的,刚刚遇到了同样的问题..我走了很长的路

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

在 .val() 函数可以被填充之前只是一个小超时。

E.

【讨论】:

  • 如果 textarea 中已经有文本并且您粘贴,而您只想要粘贴的文本怎么办?
  • 完美运行,谢谢。超时 0 也可以。该函数只需要推迟到下一个循环。
  • 刚遇到类似情况。存在超时是因为粘贴事件不是立即发生的,而是需要几毫秒才能粘贴剪贴板内容。
  • @user563811:请注意,HTML5 中官方的最小超时是 4 毫秒。
  • 就像 sharif 说的,0ms 仍然把事件放在栈底。
【解决方案2】:

您实际上可以直接从event 获取值。不过,它有点迟钝。

如果不希望通过,则返回 false。

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

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

});

【讨论】:

  • 这是要走的路
  • 即11:window.clipboardData.getData('text')
  • 但是,请注意,只有在使用 jQuery 处理事件时才需要“originalEvent”属性。您可以在纯 JavaScript 中只使用 e.clipboardData.getData('text')
  • 最佳答案在这里!但是——我觉得很奇怪,绑定的简写版本不适用于这个,即如果我尝试这个,就会出错:$(this).paste(function(e) {...});,甚至虽然这适用于短手.on('click')等......
  • niggle:代码缺少结束括号。显然更改太小,无法让我将其修复为编辑。
【解决方案3】:

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

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

【讨论】:

  • 漂亮的解决方案,既可以用作粘贴,也可以用作键位事件捕获。 注意:如果您突出显示输入内容然后至少在IE8中键入内容(不是在许多情况下很重要,但在其他情况下可能非常重要)。
  • 不错!我不知道这个,它完全符合我的需求!
【解决方案4】:

我使用以下代码修复了它:

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

现在我只需要存储插入符号位置并附加到该位置,然后我就准备好了......我想:)

【讨论】:

  • 你是如何存储插入符号位置的?
  • @Petah 您可以使用.find(':focus') 检查哪个元素具有焦点,并知道该元素为其确定插入符号的位置。见this
  • 请记住,“live”已被弃用,取而代之的是“on”
  • input 与众不同 :) 我通常在我的文本框事件 keyup keydown paste input 中有这些,但显然取决于你的动机是什么
【解决方案5】:

嗯...我认为您可以使用e.clipboardData 来捕获正在粘贴的数据。如果没有成功,请查看here

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

【讨论】:

  • 当我在 Safari 中运行它时,我得到 'undefined' :(
  • clipboardData 在大多数浏览器上被沙盒化(明显的安全漏洞。)
  • 仅限 Internet Explorer!
【解决方案6】:

监听粘贴事件并设置keyup事件监听器。在 keyup 上,捕获值并删除 keyup 事件侦听器。

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

【讨论】:

  • 这个很好,但是右键粘贴不行。
  • 它也不适用于中键粘贴 (X11),只有在他们使用键盘粘贴时才有效。
【解决方案7】:
$("#textboxid").on('input propertychange', function () {
    //perform operation
        });

它会正常工作的。

【讨论】:

    【解决方案8】:

    这越来越接近您可能想要的。

    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() ) );
       }
     });
    });
    

    请注意,当没有找到 clipboardData 对象时(在 IE 以外的浏览器上),您当前正在获取元素的完整值 + 剪贴板的值。

    如果您真的只是在真正将数据粘贴到元素中之后,您可能可以在输入之前和输入之后执行一些额外的步骤来区分这两个值。

    【讨论】:

      【解决方案9】:
       $('').bind('input propertychange', function() {....});                      
      

      这适用于鼠标粘贴事件。

      【讨论】:

      • 这是最好的用法。
      【解决方案10】:

      如何比较字段的原始值和字段的更改值,然后减去差异作为粘贴值?即使字段中存在现有文本,这也会正确捕获粘贴的文本。

      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);
          });
      });
      

      【讨论】:

        【解决方案11】:

        此代码对我有用,可以通过右键单击粘贴或直接复制粘贴

           $('.textbox').on('paste input propertychange', function (e) {
                $(this).val( $(this).val().replace(/[^0-9.]/g, '') );
            })
        

        当我将Section 1: Labour Cost 粘贴到文本框中时,它会变成1

        为了只允许浮点值,我使用此代码

         //only decimal
            $('.textbox').keypress(function(e) {
                if(e.which == 46 && $(this).val().indexOf('.') != -1) {
                    e.preventDefault();
                } 
               if (e.which == 8 || e.which == 46) {
                    return true;
               } else if ( e.which < 48 || e.which > 57) {
                    e.preventDefault();
              }
            });
        

        【讨论】:

          【解决方案12】:
          document.addEventListener('paste', function(e){
              if(e.clipboardData.types.indexOf('text/html') > -1){
                  processDataFromClipboard(e.clipboardData.getData('text/html'));
                  e.preventDefault();
          
                  ...
              }
          });
          

          进一步:

          【讨论】:

          • text/html 无效,只有 url 和 text。
          • @Mike 我直接从参考文档中复制了 sn-p。
          • 我试了大约一天。 text/html 永远不会起作用。我最终添加了 0 延迟的超时,并且能够从他们粘贴的 div 中获取 html。如果有人有一个工作小提琴会有所帮助。也许我只是做错了......
          【解决方案13】:

          请参阅此示例:http://www.p2e.dk/diverse/detectPaste.htm

          它本质上使用 oninput 事件跟踪每个更改,然后通过字符串比较检查它是否是粘贴。哦,在 IE 中有一个 onpaste 事件。所以:

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

          【讨论】:

          • 所以不可能在事件发生时只获取粘贴文本?
          • 好吧,我想你将不得不自己处理它,比如,比较之前和之后。它必须相当容易。但是你为什么不重新验证整个输入呢?慢?
          • 我只是认为这是可能的,但我猜不是,现在我正在尝试另一种方法,将其粘贴到文本区域,然后将其传输到最终目的地。我希望这会奏效。
          • 您只需要在两个字符串的开头(之前和之后)找到最大匹配片段。从那里到长度差异的所有内容都是粘贴的文本。
          • @IlyaBirman 不,不是这样:例如,粘贴的文本可能会替换原始文本的部分(或全部)
          【解决方案14】:

          这个方法使用jqueries contents().unwrap()。

          1. 首先,检测粘贴事件
          2. 为我们要粘贴的元素中已有的标签添加一个唯一的类。
          3. 在给定超时后扫描所有内容展开标签,这些标签没有您之前设置的类。注意:此方法不会删除像
            请参阅下面的示例。

            之类的自闭合标签。
            //find all children .find('*') and add the class .within .addClass("within") to all tags
            $('#answer_text').find('*').each(function () {
            $(this).addClass("within");
            });
            setTimeout(function() {
            $('#answer_text').find('*').each(function () {
                //if the current child does not have the specified class unwrap its contents
                $(this).not(".within").contents().unwrap();
            });
            }, 0);
            

          【讨论】:

          • 绝对是有史以来最好的,最短的和自言自语的答案!!!非常感谢,你让我很开心;)
          【解决方案15】:

          使用类 portlet-form-input-field 从所有字段中删除特殊字符的脚本:

          // Remove special chars from input field on paste
          jQuery('.portlet-form-input-field').bind('paste', function(e) {
              var textInput = jQuery(this);
              setTimeout(function() {
                  textInput.val(replaceSingleEndOfLineCharactersInString(textInput.val()));
              }, 200);
          });
          
          function replaceSingleEndOfLineCharactersInString(value) {
              <%
                  // deal with end-of-line characters (\n or \r\n) that will affect string length calculation,
                  // also remove all non-printable control characters that can cause XML validation errors
              %>
              if (value != "") {
                  value = value.replace(/(\x00|\x01|\x02|\x03|\x04|\x05|\x06|\x07|\x08|\x0B|\x0C|\x0E|\x0F|\x10|\x11|\x12|\x13|\x14|\x15|\x16|\x17|\x18|\x19|\x1A|\x1B|\x1C|\x1D|\x1E|\x1F|\x7F)/gm,'');
                  return value = value.replace(/(\r\n|\n|\r)/gm,'##').replace(/(\#\#)/gm,"\r\n");
              }
          }
          

          【讨论】:

          • 能否请您添加相关消毒的说明以及为什么它可能有助于解决发帖人的问题?简单地提供代码块并不能真正帮助 OP(或未来的搜索者)了解如何解决问题 - 它只会鼓励复制/粘贴被误解的代码。
          【解决方案16】:

          这被证明是非常虚幻的。在粘贴事件函数内的代码执行之前,输入的值不会更新。我尝试从粘贴事件函数中调用其他事件,但输入值仍未使用任何事件函数内的粘贴文本更新。这是除了 keyup 之外的所有事件。如果您从粘贴事件函数中调用 keyup,您可以从 keyup 事件函数中清理粘贴的文本。就这样……

          $(':input').live
          (
              'input paste',
              function(e)
              {
                  $(this).keyup();
              }
          );
          
          $(':input').live
          (
              'keyup',
              function(e)
              {
                  // sanitize pasted text here
              }
          );
          

          这里有一个警告。在 Firefox 中,如果您在每个按键上重置输入文本,如果文本长于输入宽度允许的可视区域,那么在每个按键上重置值都会破坏浏览器功能,该功能会自动将文本滚动到插入符号的位置文本的结尾。取而代之的是,文本会滚动回到开头,使插入符号不可见。

          【讨论】:

          • 在粘贴内容之前调用onpaste。您需要至少4ms的定时延迟来创建自己的afterpaste函数,以清洗粘贴的结果。
          【解决方案17】:

          这里有一个警告。在 Firefox 中,如果您在每个按键上重置输入文本,如果文本长于输入宽度允许的可视区域,那么在每个按键上重置值都会破坏浏览器功能,该功能会自动将文本滚动到插入符号的位置文本的结尾。取而代之的是,文本会滚动回到开头,使插入符号不可见。

          function scroll(elementToBeScrolled) 
          {
               //this will reset the scroll to the bottom of the viewable area. 
               elementToBeScrolled.topscroll = elementToBeScrolled.scrollheight;
          }
          

          【讨论】:

          • 这似乎完全跑题了
          • 这是对 James Tindall 给出的答案的回应。应该是评论,但已经十多年了,所以我认为诉讼时效已经过去了。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-10-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-04
          • 1970-01-01
          相关资源
          最近更新 更多