I am aware that no native events exist for select on open/close. I am using select.mousedown and document.mouseup as suggested in this answer, and they work well on desktop. However, they don't work as expected on mobile - when select is opened, both select.mousedown and document.mouseup fire, and when closed, neither fires.
Here's the code (and jsfiddle) - to reproduce the issue, open up devtools then device emulator (such as iPhone 6):
const select = document.getElementById("select")
select.addEventListener('mousedown', e => {
console.log('select mousedown')
})
document.addEventListener('mouseup', e => {
console.log('document mouseup')
})
<select id="select">
<option value="1" data-label="One">1</option>
<option value="2" data-label="Two">2</option>
<option value="3" data-label="Three">3</option>
<option value="4" data-label="Four">4</option>
</select>
I experimented with other events too trying to capture the moment when select is closed - select.blur, document.click, select.mouseleave, etc. - but none are firing on mobile. Here's a more extensive jsfiddle - open up the device emulator, open the select box, and then close it (either clicking away or on the box itself) - no events fire.
I also tried to cover the page with an invisible overlay - the problem is either I can't seem to "trickle" the click event from the overlay down to select (I tried document.elementFromPoint(e.clientX, e.clientY).click() inside overlay.click), or if I apply pointer-events: none then the overlay doesn't receive the click, only the select does.
Is there any way to listen to select open/close events on mobile? Thanks
unfortunately there is no standard event for select open and close
one way is to build a custom dropdown, like one propose by bootstrap https://getbootstrap.com/docs/4.0/components/dropdowns/#events with this one you have more event fired by the component when it is open or closed
code come from the doc
<div class="dropdown">
<button id="dLabel" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown trigger
</button>
<div class="dropdown-menu" aria-labelledby="dLabel">
...
</div>
</div>
$('#myDropdown').on('show.bs.dropdown', function () {
// do something…
})
These are the events you need to achieve the desired behavior.
const select = document.getElementById("select")
select.addEventListener('focusin', e => {
console.log('using select')
})
document.addEventListener('focusout', e => {
console.log('no longer working on select')
})
document.addEventListener('change', e => {
console.log('chose a value')
})
<select id="select">
<option value="1" data-label="One">1</option>
<option value="2" data-label="Two">2</option>
<option value="3" data-label="Three">3</option>
<option value="4" data-label="Four">4</option>
</select>