Estoy buscando una forma (o una solución alternativa) para suscribirme al cambio de índice selectedIndex (en el elemento <select> ) cuando el cambio se realiza mediante una asignación simple (como myElement.selectedIndex=1 ).
<select id = "mySelect" onchange="myListener()"> <option>0</option> <option>1</option> </select> <script> function myListener() { console.log('Yes, I hear...'); // doesn't work on selectedIndex assignment } document.getElementById('mySelect').selectedIndex = 1; </script> Parece que no es posible, pero tal vez haya alguna solución.
dispatchEvent no es una opción (la conexión del oyente se debe realizar desde el exterior).
Mi única solución hasta ahora, muy similar a @ jren510 (pero me gusta más su solución).
function myListener() { console.log('Yes, I hear...'); } const originalPropDescriptor = Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype, 'selectedIndex'); Object.defineProperty(HTMLSelectElement.prototype, 'originalSelectedIndex', originalPropDescriptor); Object.defineProperty(HTMLSelectElement.prototype, 'selectedIndex', { get() { return this.originalSelectedIndex; }, set(value) { myListener(); this.originalSelectedIndex = value; } });Me gustaría evitar anular los métodos nativos, hasta ahora es la única forma que veo.
Tal vez no sea la mejor respuesta, pero mencionaste soluciones.
Puede intentar anular el setter para el objeto para el que está tratando de detectar el cambio.
let mySelect = document.getElementById("mySelect"); const callback = () => { console.log("Yes, I hear..."); }; const original = Object.getOwnPropertyDescriptor( Object.getPrototypeOf(mySelect), "selectedIndex" ); Object.defineProperty(mySelect, "selectedIndex", { set: function (t) { callback(); return original.set.apply(this, arguments); }, get: function () { return original.get.apply(this); } }); let myButton = document.getElementById("myButton"); myButton.addEventListener("click", () => { mySelect.selectedIndex = 1; }); <select id="mySelect"> <option>0</option> <option>1</option> </select> <button id="myButton"> change selector value to 1 </button> Vale la pena mencionar que la devolución de llamada no se ejecuta cuando se cambia manualmente la selección aquí. Si desea conservar ese comportamiento, puede agregar un detector de eventos que llame a la callback de llamada como de costumbre, aunque puede existir una mejor solución que captura ambos casos.