Detect all changes to a <input type=“text”>

2018-12-31 16:21发布

There are many ways the value of a <input type="text"> can change, including:

  • keypresses
  • copy/paste
  • modified with JavaScript
  • auto-completed by browser or a toolbar

I want my JavaScript function to be called (with the current input value) any time it changes. And I want it to be called right away, not just when the input loses focus.

I'm looking for the cleanest and most robust way to do this across all browsers (using jQuery preferably).

Example use case: On the Twitter Signup page, the username field's value gets shown in the url "http://twitter/username" below it.

16条回答
几人难应
2楼-- · 2018-12-31 16:39

This is the fastest& clean way to do that :

I'm using Jquery-->

$('selector').on('change', function () {
    console.log(this.id+": "+ this.value);
});

It is working pretty fine for me.

查看更多
旧时光的记忆
3楼-- · 2018-12-31 16:40

I may be late to the party here but can you not just use the .change() event that jQuery provides.

You should be able to do something like ...

$(#CONTROLID).change(function(){
    do your stuff here ...
});

You could always bind it to a list of controls with something like ...

var flds = $("input, textarea", window.document);

flds.live('change keyup', function() {
    do your code here ...
});

The live binder ensures that all elements that exist on the page now and in the future are handled.

查看更多
泛滥B
4楼-- · 2018-12-31 16:44

We actually don't need to setup loops for detecting javaScript changes. We already setting up many event listeners to the element we want to detect. just triggering any un harmful event will make the job.

$("input[name='test-element']").on("propertychange change click keyup input paste blur", function(){
console.log("yeh thats worked!");
});

$("input[name='test-element']").val("test").trigger("blur");

and ofc this is only available if you have the full control on javascript changes on your project.

查看更多
浅入江南
5楼-- · 2018-12-31 16:45

Well, best way is to cover those three bases you listed by yourself. A simple :onblur, :onkeyup, etc won't work for what you want, so just combine them.

KeyUp should cover the first two, and if Javascript is modifying the input box, well I sure hope it's your own javascript, so just add a callback in the function that modifies it.

查看更多
残风、尘缘若梦
6楼-- · 2018-12-31 16:45

Can't you just use <span contenteditable="true" spellcheck="false"> element in place of <input type="text">?

<span> (with contenteditable="true" spellcheck="false" as attributes) distincts by <input> mainly because:

  • It's not styled like an <input>.
  • It doesn't have a value property, but the text is rendered as innerText and makes part of its inner body.
  • It's multiline whereas <input> isn't although you set the attribute multiline="true".

To accomplish the appearance you can, of course, style it in CSS, whereas writing the value as innerText you can get for it an event:

Here's a fiddle.

Unfortunately there's something that doesn't actually work in IE and Edge, which I'm unable to find.

查看更多
泛滥B
7楼-- · 2018-12-31 16:47

Unfortunately, I think setInterval wins the prize:

<input type=text id=input_id />
<script>
setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100);
</script>

It's the cleanest solution, at only 1 line of code. It's also the most robust, since you don't have to worry about all the different events/ways an input can get a value.

The downsides of using 'setInterval' don't seem to apply in this case:

  • The 100ms latency? For many applications, 100ms is fast enough.
  • Added load on the browser? In general, adding lots of heavy-weight setIntervals on your page is bad. But in this particular case, the added page load is undetectable.
  • It doesn't scale to many inputs? Most pages don't have more than a handful of inputs, which you can sniff all in the same setInterval.
查看更多
登录 后发表回答