最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery using event.preventDefault() with on('input') - Stack Overflow

programmeradmin0浏览0评论

I'm catching paste events with $('selector').on('input', function(event) { ... });

Then I'm trying to test what's been pasted and if it doesn't pass validation, cancel the paste with event.preventDefault(). Unfortunately, by the time the listener function is executed, the text has already been pasted and event.preventDefault() does nothing.

So what's a good way to catch paste events, and if what's been pasted doesn't validate, undo/prevent the paste?

I know I can use .on('paste', function(event) { ... }), but that doesn't give me the text that's been pasted or the contents of the input element after the paste, unless I use setTimeout() with some minute wait time, and I'd like to avoid using setTimeout().

I'm catching paste events with $('selector').on('input', function(event) { ... });

Then I'm trying to test what's been pasted and if it doesn't pass validation, cancel the paste with event.preventDefault(). Unfortunately, by the time the listener function is executed, the text has already been pasted and event.preventDefault() does nothing.

So what's a good way to catch paste events, and if what's been pasted doesn't validate, undo/prevent the paste?

I know I can use .on('paste', function(event) { ... }), but that doesn't give me the text that's been pasted or the contents of the input element after the paste, unless I use setTimeout() with some minute wait time, and I'd like to avoid using setTimeout().

Share Improve this question edited Sep 12, 2019 at 17:32 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Mar 3, 2013 at 3:20 Val SchumanVal Schuman 1,8182 gold badges21 silver badges25 bronze badges 5
  • Can you create a jsFiddle example? – j08691 Commented Mar 3, 2013 at 3:25
  • event.preventDefault() prevents the default action, and when binding to the input event, it does'nt really prevent you from typing or pasting anything in an input? When caching the value from pasted content, you'll have to defer it to get a value, but not "some minute", set the timeout to zero, and it should still work. – adeneo Commented Mar 3, 2013 at 3:28
  • I guess it's ok if to set 100ms timeout to capture the value of a input on paste and validate rather than a minute. – SRy Commented Mar 3, 2013 at 3:30
  • You'd just do something like this FIDDLE ? – adeneo Commented Mar 3, 2013 at 3:34
  • @adeneo The reason I'm averse to using setTimeout is because, as I understand, OS process scheduler may decide to give priorities to processes in such a way that the setTimeout function may be executed before the input element is updated with the pasted content. Though, I realize I may be pletely wrong on this... – Val Schuman Commented Mar 3, 2013 at 4:24
Add a ment  | 

4 Answers 4

Reset to default 2

First of all some background on event trigger order for the input element:

keydown -> keypress -> paste -> input -> keyup -> change

Whenever you call preventDefault it stops the chains, like nothing happened.

So my suggestion is to catch the paste event, prevent its default behavior and do your logic there.

I know I can use .on('paste', function(event) { ... }), but that doesn't give me the text that's been pasted or the contents of the input element after the paste

Actually you can retrieve the content of the clipboard. See this doc. Support is all major browser (but only IE11+). I do not know if by the time of the writing of the question this functionality was available or not.

Fiddle example

$('#myInput').on('paste', function(e) {
    // Cancel the event - this prevents the text from being entered into the input and stops the event chain
    e.preventDefault();

    // Get the content of the clipboard
    let paste = (event.clipboardData || window.clipboardData).getData('text');

    // Validate what it is pasted       
    if (paste == "text to paste") {
        // If condition is satisfied manually set the value of the input
        $(this)
            .val(paste)
            // Manually trigger events if you want
            .trigger('input')
            .trigger('change');
    }
});

Notes on the code:

  • This solution does not include setTimeout. Whenever you make it with setTimeout you see for a very short time the text being pasted, like a blinking effect.
  • If text meets condition I manually set it in the input. However this does not trigger input and change events. If you need them, just manually trigger them
  • Similar approach is to first check the text and if it does not meet requirements then call preventDefault, otherwise do nothing. This way you avoid manually setting value in the input and triggering events afterward.

Try using .change event of jquery.

Set value to blank if value doesn't satisfy your condition.

Using

$('selector').on('input', function(event) { ... }); 

and in case the validation does not pass deleting the pasted text seems to work for me.

Sadly accessing the clipboard has some flaws (browser asking if it is allowed to inspect the clipboard, cross browser patibility, etc.)

If you are okay with saving the last value of the input, the pasted text can be calculated anyway.

Here is my approach for calculating the pasted text

https://jsfiddle/f710o9qd/2/

I hope this helps you :)

(Feel free to refine the calculation of the pasted text if you find any flaws)

My understanding from the question is, we must not allow any data to be pasted inside the text box until and unless it pass a specific validation. Instead of using event.preventDefault(), we can capture the value when user input any content, using on('input') listener and validate it against the specific condition and if the validation gets failed, empty the text box value.

(This is the workaround if we still need to use on('input') event listener)

Sample Code (I am using console.log() for printing the pasted value):

HTML:

<input type='text' id="selector" />

JS:

$(document).ready(function() {
 $('#selector').on('input', function (e){
        if(e.target.value !== "myValue"){
        $('#selector').val('');
    }
    else{
        console.log(e.target.value);
    }
 });
});
发布评论

评论列表(0)

  1. 暂无评论