javascript - Is there a way to listen to textbox when its value is changed programmatically - Stack Overflow

Environment:Only JavaScript (no jquery :( )Button click event handler is not available for change.Is

Environment:
Only JavaScript (no jquery :( )
Button click event handler is not available for change.

Is there a way to listen to textbox if its value is changed programmatically?

<input type="button" id="button1" value="button" />
<input type="text" id="text1" />


var btn1 = document.getElementById('button1');
var txt1 = document.getElementById('text1');
btn1.onclick=function(){ txt1.value = 'hello world'}

/

Environment:
Only JavaScript (no jquery :( )
Button click event handler is not available for change.

Is there a way to listen to textbox if its value is changed programmatically?

<input type="button" id="button1" value="button" />
<input type="text" id="text1" />


var btn1 = document.getElementById('button1');
var txt1 = document.getElementById('text1');
btn1.onclick=function(){ txt1.value = 'hello world'}

https://jsfiddle/yrt7e57w/

Share Improve this question edited Jun 22, 2017 at 20:32 lewis4u 15.1k22 gold badges113 silver badges158 bronze badges asked Jun 22, 2017 at 20:01 RodRod 15.5k35 gold badges134 silver badges264 bronze badges 8
  • txt.onchange=function(){}... – Jonas Wilms Commented Jun 22, 2017 at 20:03
  • 1 i think i tried that and it didn't work for me - jsfiddle/yrt7e57w/1 – Rod Commented Jun 22, 2017 at 20:03
  • Did you try using the add event function and giving it the 'change' event type? – Carcigenicate Commented Jun 22, 2017 at 20:05
  • And note your example installs a onclick listener, not an onchange one. – Carcigenicate Commented Jun 22, 2017 at 20:06
  • 1 Programmatic changes don't trigger onchange, onclick, onAnything -- you'd have to make changes to the Object object itself to trigger something. Take a look at stackoverflow./questions/19325938/… -- possible duplicate. – Snowmonkey Commented Jun 22, 2017 at 20:07
 |  Show 3 more ments

3 Answers 3

Reset to default 4

You can use element.dispatchEvent(event) when you change the text programmatically. In your example it would look like:

var btn1 = document.getElementById('button1');
var txt1 = document.getElementById('text1');

btn1.addEventListener("click", function() { // Add to OnClick of button.
    txt1.dispatchEvent(new Event('change')); // force change event to run on textbox.
});

txt1.addEventListener("change", function(e){ // EventListener for OnChange of the element.
    alert("changed");
});

Just the addEventListener on its own will not work as it isn't exactly being changed in the DOM.

Above is a simple solution which requires a few key presses but for a much more maintainable and reusable solution, check out Snowmonkey's answer (and probably most other answers to this question), https://stackoverflow./a/44708746/640263.

You can rely on the coder programmatically changing the element to know to trigger the onChange, but that's an iffy proposition. Looking through other posts, this looks very promising: for your text element, override the setters and getters, so that they automagically trigger for either keyed changes or programattic ones.

var btn1 = document.getElementById('button1');
var txt1 = document.getElementById('text1');


btn1.onclick = function() {
    txt1.value = 'hello world'
  }
  
txt1.addEventListener("change", function(e){
  console.log(txt1.value);
})
  
  //property mutation for hidden input
Object.defineProperty(txt1, "value", {
  // Don't override the getter, but stub it in.
  get: function() {
    return this.getAttribute("value");
  },
  // In the setter, we want to set the value
  //  and also fire off the change event.
  //  By doing this, the coder changing the
  //  value never needs worry about it.
  set: function(val) {
    console.log("set");

    // handle value change here
    this.setAttribute("value", val);

    //fire the event
    if ("createEvent" in document) { //NON IE browsers
      var evt = document.createEvent("HTMLEvents");
      evt.initEvent("change", false, true);
      txt1.dispatchEvent(evt);
    } else { //IE
      var evt = document.createEventObject();
      txt1.fireEvent("onchange", evt);
    }
  }
});
<input type="button" id="button1" value="button" />
<input type="text" id="text1" />

Or see it as a fiddle Here

So, to answer your question about why the click handler is showing the input as having a null value, it's because the getter/setter are overriding the default value behavior. The easiest way to work around this is to create a custom getter/setter to act as an interface to the value attribute:

var btn1 = document.getElementById('button1');
var txt1 = document.getElementById('text1');

btn1.onclick = function() {
  console.log("in the button's click handler, ");
  console.log("Value is: " + txt1.val);
  console.log("--------------------------------")
  txt1.val = 'hello world'
}

txt1.addEventListener("change", function(e) {
  console.log("in txt1.onChange function...")
  console.log(this.val);
  console.log("--------------------------------")
})


//property mutation for hidden input
Object.defineProperty(txt1, "val", {
  get: function() {
    return this.value;
  },
  set: function(val) {
    // handle value change here
    this.value = val;

    //fire the event
    if ("createEvent" in document) { //NON IE browsers
      var evt = document.createEvent("HTMLEvents");
      evt.initEvent("change", false, true);
      txt1.dispatchEvent(evt);
    } else { //IE
      var evt = document.createEventObject();
      txt1.fireEvent("onchange", evt);
    }
  }
});
<input type="button" id="button1" value="button" />
<input type="text" id="text1" />

What's happening here is, when the button is clicked, I get the val attribute of the input (which gets the value behind the scenes), then programmatically sets the val attribute of the same input (which, again, sets the value attribute). For some reason, you can't use get/set in object.defineProperty on an input's value attribute without pletely breaking it. So in the console, you'll see THREE function calls: when you click the button, the input loses focus, triggering its change method, but then the button itself triggers its click handler, which then changes the value of the input and triggers the change handler one more time.

Hope this helps!

Again, to see this as a fiddle...

Maybe this is overkill,
but you could use the mutationObserver api to listen to an attribute change,
you would then have to change the value through setAttribute method:

var btn1 = document.getElementById('button1');
var txt1 = document.getElementById('text1');

btn1.onclick=function(){ txt1.setAttribute('value', 'hello world') }

// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log( mutation );
  });    
});
 
// configuration of the observer:
var config = {  attributes:true };
 
// pass in the target node, as well as the observer options
observer.observe(txt1, config);
<input type="button" id="button1" value="button" />
<input type="text" id="text1" />

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744095218a4557820.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信