我可以将 EventListener 放在 <option> 元素上吗?
Can I put an EventListener on an <option> element?
我正在尝试将 EventListener
添加到 <option>
元素。
我尝试了各种方法,但没有结果。
我正在使用 VueJS,所以我尝试使用他们的事件绑定机制。
VueJS - 事件绑定 - 仅适用于 <select>
<select @mouseover="testValue = true" @mouseleave="testValue = false" ref="select">
<option v-for="(option, index) in selectionSet" :key="index"
:value="option.id" :disabled="option.disabled" @mouseover="testValue = true" @mouseleave="testValue = false">
{{option.name}}
</option>
</select>
所以接下来我自然而然地采用了 RAW plainJS 方式。
PlainJS - AddEventListener() - 元素有效,但 eventListener 不会被注册
this.$refs.select.options.forEach((el) => {
el.addEventListener('pointerover', () => { window.console.log('AAAAH'); });
if (!el.disabled) window.console.log(el.value);
});
是的,我使用了多个事件名称。
那怎么办? -> 阅读文档
调查<option>
documentation on MDN, I can see, that the <option>
has the HTMLOptionElement
DOM Interface. This interface is supposed to have all Properties and Methods inherited from HTMLElement
。
The HTMLOptionElement interface represents elements and inherits all properties and methods of the HTMLElement interface. - MDN
所以我想知道,我能否以某种方式将 eventListeners 注册到 <option>
元素?
问题不在于在元素上注册事件处理程序,而是浏览器不会在下拉列表中的 option
元素(或者至少,不能可靠地跨浏览器)触发事件select
个元素。
例如,Chrome 和 Firefox 不会在下拉 select
元素中的 option
元素上触发任何事件,即使你可以在它们上注册事件处理程序,甚至在它们上触发您自己的事件。例如,在下面,Chrome 或 Firefox 不会在 option
元素上自动触发任何事件,但是如果您单击按钮明确地触发一个,它会起作用:
const option = document.querySelectorAll("option")[1];
function optionEventHandler(event) {
console.log(event.type, this.textContent);
}
// None of these fire on Chrome except when code explicitly
// does it with `dispatchEvent`, as far as I can tell:
for (const eventName of ["click", "mouseover", "pointerover", "mouseenter"]) {
option.addEventListener(eventName, optionEventHandler);
}
document.querySelector("select").addEventListener("click", function() {
console.log("click on select", this.value);
});
// Explicitly firing an event at the element:
document.querySelector("input[type=button]").addEventListener("click", function() {
option.dispatchEvent(new Event("click"));
});
<select>
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
<option>E</option>
</select>
<div>
<input type="button" value="Send 'click' to B">
</div>
很遗憾,如果您想在指针位于选项上方时执行某些操作,则必须使用 select
和 option
以外的其他选项。当指针从列表中的一个 option
移动到下一个
时,Chrome 和 Firefox 甚至都不会在 document
触发 pointerover
。
为了完整起见,请注意某些事件(包括 pointerover
)在非下拉 select
元素中起作用,至少在 Chrome 和 Firefox 上是这样:
const option = document.querySelectorAll("option")[1];
function optionEventHandler(event) {
console.log(event.type, this.textContent);
}
// None of these fire on Chrome except when code explicitly
// does it with `dispatchEvent`, as far as I can tell:
for (const eventName of ["click", "mouseover", "pointerover", "mouseenter"]) {
option.addEventListener(eventName, optionEventHandler);
}
document.querySelector("select").addEventListener("click", function() {
console.log("click on select", this.value);
});
// Explicitly firing an event at the element:
document.querySelector("input[type=button]").addEventListener("click", function() {
option.dispatchEvent(new Event("click"));
});
<select size="5">
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
<option>E</option>
</select>
<div>
<input type="button" value="Send 'click' to B">
</div>
我正在尝试将 EventListener
添加到 <option>
元素。
我尝试了各种方法,但没有结果。 我正在使用 VueJS,所以我尝试使用他们的事件绑定机制。
VueJS - 事件绑定 - 仅适用于 <select>
<select @mouseover="testValue = true" @mouseleave="testValue = false" ref="select">
<option v-for="(option, index) in selectionSet" :key="index"
:value="option.id" :disabled="option.disabled" @mouseover="testValue = true" @mouseleave="testValue = false">
{{option.name}}
</option>
</select>
所以接下来我自然而然地采用了 RAW plainJS 方式。
PlainJS - AddEventListener() - 元素有效,但 eventListener 不会被注册
this.$refs.select.options.forEach((el) => {
el.addEventListener('pointerover', () => { window.console.log('AAAAH'); });
if (!el.disabled) window.console.log(el.value);
});
是的,我使用了多个事件名称。
那怎么办? -> 阅读文档
调查<option>
documentation on MDN, I can see, that the <option>
has the HTMLOptionElement
DOM Interface. This interface is supposed to have all Properties and Methods inherited from HTMLElement
。
The HTMLOptionElement interface represents elements and inherits all properties and methods of the HTMLElement interface. - MDN
所以我想知道,我能否以某种方式将 eventListeners 注册到 <option>
元素?
问题不在于在元素上注册事件处理程序,而是浏览器不会在下拉列表中的 option
元素(或者至少,不能可靠地跨浏览器)触发事件select
个元素。
Chrome 和 Firefox 不会在下拉 select
元素中的 option
元素上触发任何事件,即使你可以在它们上注册事件处理程序,甚至在它们上触发您自己的事件。例如,在下面,Chrome 或 Firefox 不会在 option
元素上自动触发任何事件,但是如果您单击按钮明确地触发一个,它会起作用:
const option = document.querySelectorAll("option")[1];
function optionEventHandler(event) {
console.log(event.type, this.textContent);
}
// None of these fire on Chrome except when code explicitly
// does it with `dispatchEvent`, as far as I can tell:
for (const eventName of ["click", "mouseover", "pointerover", "mouseenter"]) {
option.addEventListener(eventName, optionEventHandler);
}
document.querySelector("select").addEventListener("click", function() {
console.log("click on select", this.value);
});
// Explicitly firing an event at the element:
document.querySelector("input[type=button]").addEventListener("click", function() {
option.dispatchEvent(new Event("click"));
});
<select>
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
<option>E</option>
</select>
<div>
<input type="button" value="Send 'click' to B">
</div>
很遗憾,如果您想在指针位于选项上方时执行某些操作,则必须使用 select
和 option
以外的其他选项。当指针从列表中的一个 option
移动到下一个
document
触发 pointerover
。
为了完整起见,请注意某些事件(包括 pointerover
)在非下拉 select
元素中起作用,至少在 Chrome 和 Firefox 上是这样:
const option = document.querySelectorAll("option")[1];
function optionEventHandler(event) {
console.log(event.type, this.textContent);
}
// None of these fire on Chrome except when code explicitly
// does it with `dispatchEvent`, as far as I can tell:
for (const eventName of ["click", "mouseover", "pointerover", "mouseenter"]) {
option.addEventListener(eventName, optionEventHandler);
}
document.querySelector("select").addEventListener("click", function() {
console.log("click on select", this.value);
});
// Explicitly firing an event at the element:
document.querySelector("input[type=button]").addEventListener("click", function() {
option.dispatchEvent(new Event("click"));
});
<select size="5">
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
<option>E</option>
</select>
<div>
<input type="button" value="Send 'click' to B">
</div>