Intenté escribir un elemento inspirado personalizado con un campo de entrada donde el usuario puede escribir y una lista que aparece y desaparece según el enfoque de la entrada.
const unitsList = {lenght:{fm:"femtometers (fm)",pm:"picometers (pm)",nm:"nanometers (nm)",um:"micrometers (μm)",mm:"millimiters (mm)",cm:"centimiters (cm)",dm:"decimeters (dm)",m:"meters (m)",dam:"decameters (dam)",hm:"hectometers (hm)",km:"kilometers (km)",in:"inchs (in)",ft:"foots (ft)",yd:"yards (yd)",mi:"miles (mi)"}} let groups = ['lenght', ] function $$(id) { return document.querySelectorAll(id); } function s$(id) { return document.querySelector(id); } $$('ul').forEach(selector => { for (group of groups) { for (unit in unitsList[group]) { selector.insertAdjacentHTML('beforeend', `<li onclick="console.log('${unit}')">${unitsList[group][unit]}</li>`); } } }) $$('.customSelectorInput').forEach(input => { input.addEventListener('focus', () => { $$('ul').forEach(() => { s$(`#${input.parentNode.id} > ul`).hidden = false; }) }) }) $$('.customSelectorInput').forEach(input => { input.addEventListener('blur', () => { $$('ul').forEach(() => { s$(`#${input.parentNode.id} > ul`).hidden = true; }) }) }) ul { position: absolute; list-style: none; padding-left: 10px; margin: 5px; background-color: lightgray; padding: 5px; border-radius: 5px; height: 100px; overflow-y: scroll; } li { margin: 2px 0; padding: 5px; } li:hover { background-color: grey; } <div class="inputContainer"> <div id="inSelector"> <input type="text" class="customSelectorInput"> <ul hidden id="inList"></ul> </div> </div> El problema es que la entrada pierde el foco cuando el usuario hace clic en la lista y eso sucede antes de que onclick pueda funcionar. Probé varios métodos, incluidos, entre otros, event.stopPropagation() , deshabilitando useCapture o reenfocando la entrada en el controlador de eventos de clic de una lista, pero nada parece funcionar.
Realmente agradecería la ayuda de alguien.