This may not directly answer your question, but this problem could be solved by simple design level adjustments. I understand this may not be 100% applicable to all use-cases, but I strongly urge you to consider re-thinking your user flow of your application and if the following design suggestion can be implemented.
I decided to do something simple than hacking alternatives for onChange()
using other events that were not really meant for this purpose (blur
, click
, etc.)
The way I solved it:
Simply pre-pend a placeholder option tag such as select that has no value to it.
So, instead of just using the following structure, which requires hack-y alternatives:
<select>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Consider using this:
<select>
<option selected="selected">Select...</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
So, this way, your code is a LOT more simplified and the onChange
will work as expected, every time the user decides to select something other than the default value. You could even add the disabled
attribute to the first option if you don't want them to select it again and force them to select something from the options, thus triggering an onChange()
fire.
At the time of this answer, I'm writing a complex Vue application and I found that this design choice has simplified my code a lot. I spent hours on this problem before I settled down with this solution and I didn't have to re-write a lot of my code. However, if I went with the hacky alternatives, I would have needed to account for the edge cases, to prevent double firing of ajax requests, etc. This also doesn't mess up the default browser behaviour as a nice bonus (tested on mobile browsers as well).
Sometimes, you just need to take a step back and think about the big picture for the simplest solution.
<select>
is for. We should be using a list for this type of thing and handle with click events. – Neddy