【问题标题】:How to alert after paste event in Javascript?如何在Javascript中粘贴事件后发出警报?
【发布时间】:2012-12-15 18:43:57
【问题描述】:

我有一个简单的过去事件

document.getElementById('paste_area').addEventListener('paste', function() {
    document.getElementById('notice').innerHTML='Text was successfully pasted!';
    alert('Pasted');
}, true);

可以在这里找到一个工作示例http://jsfiddle.net/XEQzz/

警告和通知将在粘贴前出现。 如何在粘贴事件实际完成后延迟警报操作?

【问题讨论】:

  • 使用setTimeout(具有最小延迟,例如零)来推迟脚本的执行。
  • 您可以使用 preventDefault() (或 IE 等效变量 - 我忘记名称)设置自己的粘贴处理程序,但更简单的方法是使用输入事件 stackoverflow.com/a/241158/1162141,因为 (IIRC) 它还可以处理拖放文本
  • @technosaurus paste handler 不是防弹和跨浏览器。例如,FireFox 不允许访问粘贴数据。

标签: javascript dom-events


【解决方案1】:

您可以将警报放在setTimeout

setTimeout(function() {alert('Pasted');}, 0);

这将延迟代码直到值更新后。

请记住,setTimeout 回调中的 this 与封闭环境中的值不同。

如果您需要对外部 this 的引用,这将是元素,然后在变量中引用它...

var self = this;
setTimeout(function() {alert(self.value);}, 0);

或者使用.bind() (在大多数支持addEventListener的浏览器中都支持。旧版Safari不支持。)...

setTimeout(function() {alert(this.value);}.bind(this), 0);

【讨论】:

  • “这个”不一样!这救了我,谢谢,很好的解释:)
  • 这是一个 hack,但在一行中它是一个漂亮的 hack!这个对我有用。谢谢;)
【解决方案2】:

setTimeout 似乎是最好的选择,你可以使用这样的东西来概括

// 对象定义

    function PasteMonitor(element)
    {
        if(typeof element == "string")
        {
            this.target = document.getElementById(element);
        }
        else if(typeof element == "object" || typeof element == "function")
        {
            this.target = element;
        }

        if(this.target != null && this.target != undefined)
        {
            this.target.addEventListener('paste',this.inPaste.bind(this),false);
            this.target.addEventListener('change',this.changed.bind(this),false);
        }
        this.oldstate = "";
    }
    PasteMonitor.prototype = Object.create({},{
        pasted:{ value: false, enumerable: true, configurable: true, writable: true },
        changed:{ value: function(evt){
            //elements content is changed
            if(typeof this.onChange == "function")
            {
                this.onChange(evt);
            }
            if(this.pasted)
            {
                if(typeof this.afterPaste == "function")
                {
                    this.afterPaste(evt);
                    this.pasted = false;
                }
            }
        }, enumerable: true, configurable: true, writable: true },
        inPaste:{ value: function(evt){
            var cancelPaste = false;
            if(typeof this.beforePaste == "function")
            {
                // process pasted data
                cancelPaste = this.beforePaste(evt);
            }
            if(cancelPaste == true)
            {
                evt.preventDefault();
                return false;
            }
            this.pasted = true;
            setTimeout(function(){
                var evt = document.createEvent("HTMLEvents");
                evt.initEvent("change", false, true);
                this.target.dispatchEvent(evt);
            }.bind(this),0);
        }, enumerable: true, configurable: true, writable: true }
    })
    PasteMonitor.prototype.constructor = PasteMonitor;

//PasteMonitor 用法

    //var element = document.getElementById('paste_area');
    var msgArea = document.getElementById('message');
    var myMonitor = new PasteMonitor("paste_area");
    //or use and object as argument => var myMonitor = new PasteMonitor(element);

    myMonitor.onChange = function(evt){
        if(this.pasted)
        {
            //do something on paste change
            msgArea.innerHTML = "onChange by paste";
            this.oldstate = this.target.value;
        }
        //check to prevent processing change event when the element loses focus if the change is done by paste
        else if(this.target.value != this.oldstate)
        {
            msgArea.innerHTML = "onChange by typing";
        }
    };
    myMonitor.afterPaste = function(evt){
       // do something after paste
        msgArea.innerHTML = "afterPaste";
    };
    myMonitor.beforePaste = function(evt){
        // do something before the actual paste
        msgArea.innerHTML = "beforePaste";
        //return true to prevent paste
        return false;
    };

【讨论】:

    【解决方案3】:

    为了更新自己的价值

     $(".number").on("paste", function (e) {
            var Value = e.originalEvent.clipboardData.getData('text');
            var Self=this
            setTimeout(function () {
                if (Value != Value.replace(/[^\d\.]/g, "")) {
                    $(Self).val(Value.replace(/[^\d\.]/g, ""));
                }
            }, 0);
        });
    

    【讨论】:

    • clipboardData 是一种更简洁的方法,但不幸的是 IE 不支持它
    • 函数event.clipboardData.getData("text")运行良好,没有超时。但是,应该注意它只返回被粘贴的值,而不是输入元素的新值。 例如:输入元素的值最初是“我的值”;然后将“SuPeR”粘贴到中间某处,新值为“my SuPeRvalue”;在这种情况下,event.clipboardData.getData("text") 将只返回“SuPeR”。如果需要获取更新后的输入元素的值——而不是粘贴的值——setTimeout 是唯一的选择。
    【解决方案4】:

    我通常这样做是为了模仿 onafterpaste。

    我有一个叫做“onafterpaste”的特殊功能,我像这样使用它:

    onpaste="onafterpaste(myFunction, this)"

    如您所见,它还接受一个额外的参数,该参数将在调用 myFunction 时使用。

    查看(并在其中尝试)以下现场 sn-p:

    function onafterpaste(f,elm) {
      setTimeout(function() {f(elm)},0);
    }
    
    function  myFunction(elm) {
      alert('After the paste, the input has the following text:\r\n\r\n'+elm.value);
    }
    <p>Paste something down here:</p>
    <input type="text" onpaste="onafterpaste(myFunction,this)" value="The original text">

    【讨论】:

      【解决方案5】:

      paste_area 是输入吗? inputalso an event

      document.getElementById('paste_area').addEventListener('input', 
          function(event) {
              alert('Pasted');
      });
      

      【讨论】:

      • 不工作:input 事件也会在 被粘贴的内容出现在 DOM 元素中之前触发。
      • 看起来对我有用:jsfiddle.net/9shcqnxo
      • 我正在尝试使用 Chrome,您的 sn-p 确认它不起作用:在文本实际粘贴到文本字段之前出现警报。
      • 警报确实在粘贴后发生(如填充正确数据所示),但不是在 GUI 更新后发生。见stackoverflow.com/a/42986563/1923095
      • sn-p 中的警报发生在粘贴之前。这正是 OP 试图解决的问题。你的答案没有。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-27
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多