Reputation: 49
I understand that if you change some property in DOM it is reflected in UI and event.preventDefault() function prevents the default changes . Now in this script i changed DOM and stopped default action but it is not reflecting in interace ?
let check = document.getElementById('check');
check.onclick = function(event) {
event.target.checked = !event.target.checked;
event.preventDefault();
}
<input id="check" type="checkbox" /> Checkbox
Upvotes: 2
Views: 730
Reputation: 49
Thanks for all the help guys , After digging i came to this conclusion that:
1) Initially the browser toggles the checked value and calls the event listener
2) Now it again encounters a toggle statement and it toggles the value again , now the value is back to original
3) Now preventDefault() is called which is executed after the bubble of eventlisteners (i think) and it sees that the new value of checked is same as the initial value(which i think it keeps track of ) and does nothing (if it was changed it would toggle again).
If you replace the line - event.target.checked = !event.target.checked; you can see preventDefault() toggling but in this case it does not toggle .
Upvotes: 1
Reputation: 1074949
In this specific example, of course, you could just not have the handler. But you've indicated in the comments that the situation is more complex than shown in the question.
You have to let the event finish being processed before you can change the checked state of the box and have that change stick, for instance with the old setTimeout(..., 0)
trick:
let check = document.getElementById('check');
check.addEventListener("click", function({target}) {
setTimeout(() => {
target.checked = !target.checked;
}, 0);
event.preventDefault();
});
<input id="check" type="checkbox" /> Checkbox
(Just a microtask like Promise.resolve().then(...)
doesn't work, at least on Chrome, apparently you have to go back to the main event loop.)
That example also uses addEventListener
rather than onclick
and ES2015+ destructuring (the {target}
in the function parameter list), since you're using let
and so appear to be using ES2015+.
But it works using onclick
, too:
let check = document.getElementById('check');
check.onclick = function({target}) {
setTimeout(() => {
target.checked = !target.checked;
}, 0);
event.preventDefault();
};
<input id="check" type="checkbox" /> Checkbox
Upvotes: 4