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
5Xx or 4Xx Error with "No 'Access-Control-Allow-Origin' Header Is Present"
JavaScript Checking for Null VS. Undefined and Difference Between == and ===
Es6 Variable Import Name in Node.Js
How to Get Current Value of Rxjs Subject or Observable
How to Split the Ng-Repeat Data with Three Columns Using Bootstrap
How to Validate Date with Format "Mm/Dd/Yyyy" in JavaScript
How to Convert a Currency String to a Double with JavaScript
How to Pass the Value (Not the Reference) of a Js Variable to a Function
Convert Base64 to Image in JavaScript/Jquery
Comparing Arrays of Objects in JavaScript
Parse Date Without Timezone JavaScript
How Does the New Operator Work in JavaScript
Event When Window.Location.Href Changes
How to Prevent Page from Reloading After Form Submit - Jquery
How to Disable an <Option> in a <Select> Based on Its Value in JavaScript
Parsing "Relaxed" JSON Without Eval
Difference Between Element.Value and Element.Getattribute("Value")