Is this a core misunderstanding of the default cli

2019-01-26 15:36发布

问题:

When binding to a click event for a checkbox input, the checkbox is already toggled by the time my event handler runs and, more oddly, the toggle is reversed after my event handler runs if I specify event.preventDefault();

<input id="foo" type="checkbox"/>

function clicked(evt) {
   alert(document.getElementById('foo').checked);
   evt.preventDefault();
}

document.getElementById('foo').addEventListener('click',clicked);

[tested in chrome and firefox]

JSFiddle for that code

The alert will respond "true" (or the opposite state of the checkbox pre-click). After you dismiss the alert, the checkbox toggles back.

So, I guess the questions are,

What is the actual default event being prevented? Am I wrong in assuming my event handler should be running before the state is changed? Is there a way to legitimately intercept a checkbox click?

And why in the world is the preventDefault causing the re-toggling the checkbox?

回答1:

The actual default event being prevented is the click event. The misunderstanding probably occurs because you are thinking of the event as firing after the actual click has been fully processed (i.e. the checkbox has been toggled) while in reality the event model stipulates that the handler fires while the event is being processed.

If it helps, another model I 've found useful in explaining how it all works is the database transaction model: think of your event handler as being invoked as part of a transaction, inside which the checkbox has already been toggled.

  • If you read the state of the checkbox, you will find it toggled (the "write" has been sent to the database).
  • However, you can still decide to rollback the transaction (in which case the write is undone and the checkbox is toggled back to its original value).