Does the Onchange Event Propagate

Does the onchange event propagate?

According to specification, change, submit, reset should bubble and focus and blur should not bubble.

This behavior is implemented properly in all web browsers except IE < 9, that is, change, submit, reset do bubble properly in IE >= 9.

See https://stackoverflow.com/a/4722246/227299 for a jQuery workaround on old IE versions

  • http://www.quirksmode.org/dom/events/change.html
  • http://quirksmode.org/dom/events/submit.html

Angular onChange doesn't trigger event.stopPropagation to prevent outer div's click

there are 2 solutions here. 1st: call stopPropagation on click

<input
type="checkbox"
id="checkbox-1"
(click)="stopPropagation($event)"
(change)="clickChild()"
/>

2nd: filter out events where the checkbox is clicked in parent handler

clickParent(event) {
if(event.target.id != 'checkbox-1') {
console.log('Click parent');
}
}

Force input's onChange event bubble to parent form with the value stored in the state

Update your CustomSelect component with the following:

class CustomSelect extends React.Component {

...

// you'll use this reference to access the html input.
ref = React.createRef();

handleSelect = item => {
this.setState({ selected: item });

// React overrides input value setter, but you can call the
// function directly on the input as context
const inputValSetter = Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype,
"value"
).set;
inputValSetter.call(this.ref.current, "dummy");

// fire event
const ev = new Event("input", { bubbles: true });
this.ref.current.dispatchEvent(ev);
};

...

render() {
...

return (
<div className="custom-select">
<input
// you'll use the reference in `handleSelect`
ref={this.ref}
name={this.props.name}
required
style={{ display: "none" }} // or type="hidden", whatever
value={selected ? selected.id : ""}
onChange={() => {}}
/>

...

</div>
);
}

...
}

And your Form component with the following:

class Form extends React.Component {

handleChange = event => {
console.log("Form onChange");

// remove synthetic event from pool
event.persist();
};

...
}

Stop propagation of all events

As I thought it was possible to do it in this way. You can create some auxilliary variable/property and set the keyCode to it in the onKeyDown handler. Then you are able to use this conditionally wherever you want (for me, in the onChange event handler).

React event propagation doesn't really stop

The change and click events are different events. When a radio button is being clicked, its change event will fire. But, the list item was also clicked, and its click event will therefore fire at the same time. Stopping the propagation of the change event won't affect the click event.

To solve this, you could stop the propagation of the radio button's click event:

<li onClick={this.onVote}>
<input
...
onChange={this.onVote}
onClick={event => event.stopPropagation()}
/>
Donald
</li>

Here's an updated fiddle: https://jsfiddle.net/cpwsd3ya/

Event bubbling in react doesn't stop using e.preventDefault()

If you only want the th click handler to fire when it is clicked on directly, you can check the target:

<th onClick={e => {
if (e.currentTarget === e.target) {
alert('fire');
}
}}>

The other option is to add a click handler to the input with a stopPropagation call:

<input onChange={e=>{e.preventDefault();alert('change text')}} onClick={e => e.stopPropagation()}/>

MDN details on currentTarget:

Identifies the current target for the event, as the event traverses the DOM. It always refers to the element to which the event handler has been attached, as opposed to event.target which identifies the element on which the event occurred.

https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget

How do I programmatically force an onchange event on an input?

Create an Event object and pass it to the dispatchEvent method of the element:

var element = document.getElementById('just_an_example');
var event = new Event('change');
element.dispatchEvent(event);

This will trigger event listeners regardless of whether they were registered by calling the addEventListener method or by setting the onchange property of the element.


By default, events created and dispatched like this don't propagate (bubble) up the DOM tree like events normally do.

If you want the event to bubble, you need to pass a second argument to the Event constructor:

var event = new Event('change', { bubbles: true });

Information about browser compability:

  • dispatchEvent()
  • Event()

Change event before it propagates to next listener?

You can't "change" a KeyboardEvent. It's read-only.

It took a while, but apparently it IS the same object that gets passed to all the event listeners.. I messed with the get properties of Event and KeyboardEvent and the edited event passes smoothly :D

window.focus();

function control(event){
const eventMap=new WeakMap()
const getMap=(instance,key)=>{
let map=eventMap.get(instance)
if(!map){
map={[key]:{value:null,valueSet:false}}
eventMap.set(instance,map)
}
if(!map[key]){map[key]={value:null,valueSet:false}}
return map[key] //specific to an event instance AND key
}
if(typeof event=='function'){event=event.prototype}
let properties=Object.getOwnPropertyDescriptors(event)
Object.keys(properties)
.filter(key=>
typeof(properties[key].get)=='function'
)
.forEach(key=>{
const original=properties[key].get
function set(something){
let map=getMap(this,key)
map.value=something; map.valueSet=true
}
function get(){
let {value,valueSet}=getMap(this,key)
return valueSet? value: original.call(this)
}
properties[key]={...properties[key],get,set}
})
Object.defineProperties(event,properties)
}
//for any event class given to it, this function makes its prototype functions malleable
control(KeyboardEvent); control(Event)
//not all but A LOT of the prototypes including shiftKey fall under these 2 classes

//eventListener that I assume you control and add first
window.addEventListener("keypress", e =>
{
e.shiftKey=!e.shiftKey //your edit to the event(switches the shiftKey event locally and not globally)
})

//event listener that might be in the environment that you didn't make
window.addEventListener("keypress", e =>
{
console.log("shift", e.shiftKey); //false when u use shift, true when u don't use shift now >:D
});

console.log("press an unshifted letter in this area")


Related Topics



Leave a reply



Submit