What event fires after you click on <select> but select no option?

Viewed 499

I'm trying to trigger a cleanup function after <select> is opened, but no option is selected and the user clicks away.

I tried change and blur, but none of them fire.

Sample and visuals

const select = document.querySelector('select');

select.addEventListener('blur', () => {
    console.log('blur');
});
<select>
  <option>one</option>
  <option>two</option>
  <option>three</option>
</select>

first sate

I click on the <select> and then without selecting an option, I click outside of it. The blur event is not triggered until I do a second click after the first outside click.

second state

2 Answers

There's no such event that signifies that the <select> is opened, but no option is selected and the user clicks away.

However, for <select> element, you can bind to click event which does not warrant the selection of an option to fire and write custom logic. I just noticed that it requires 2 clicks on <select> element for an option to be selected and for opening it only needs 1 click. With the click count, we can determine if the preconditions meet and accordingly run the cleanup code:

var clicks = 0,
    $select = document.getElementById('select');
$select.onclick = function() {
  clicks++;

  if (clicks === 2) {
    clicks = 0;
  }
};
$select.onblur = function(e) {
  if (clicks === 1) {
    clicks = 0;

    // SELECT WAS OPENED BUT NO OPTION SELECTED
    // CLEANUP CODE GOES HERE

    console.log('CLEAN UP');
  }
};
<select id="select">
  <option>A</option>
  <option>B</option>
</select>

Like @leisheng and @Kaiido suggest, this is not universal solution and will only work with desktops and mouse.

As far as what events occur when you open a select menu there are many. There may very well be a way to create your own CustomEvent and fire it by tracking the other events. If you can see what events are happening, you might be able to figure something out. This is a script I use to find all events that are occurring on an EventTarget:

EventTarget.prototype.__original_addEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(listener, callback) {
    if (listener === 'event') {
        for (let key in this) {
            if (key.startsWith('on')) {
                let eventName = key.substr(2, key.length);
                this.__original_addEventListener(eventName,
                function(e) {
                    callback(e);
                });
            }
        }
    } else {
        this.__original_addEventListener(listener, callback);
    }
};

window.onload = function() {
    document.querySelector('#id-of-my-select-tag').addEventListener('event', (e) => {
        console.log(e.type);
    });
};

This just allows you to add a listener called 'event' which captures all events. This will output all the events happening and maybe you will see a pattern that helps you write some code to detect when it is open based on the events that occurred and the order in which they occurred. (Tested in Firefox, Chrome and Edge)

Related