是否可以监听 selectedIndex 的变化?

Is it possible to listen for selectedIndex change?

我正在寻找一种方法(或解决方法)来订阅 selectedIndex 更改(在 <select> 元素上),当通过简单赋值(如 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>

似乎不​​可能,但也许有一些解决方法。
dispatchEvent 不是一个选项(监听器附件必须从外部完成)。


到目前为止我唯一的解决方案,与@jren510 非常相似(但我更喜欢他的解决方案)。

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;
    }
});

我想避免覆盖本机方法,到目前为止这是我看到的唯一方法。

也许不是最佳答案,但您确实提到了解决方法..

您可以尝试覆盖您要检测其中更改的对象的 setter。

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>

值得一提的是,在此处手动更改 select 时,回调不会 运行。如果您想保留该行为,您可以添加一个调用 [=12= 的事件侦听器] 像往常一样,虽然可能存在一个更好的解决方案来捕获这两种情况。