HTMLOptionElement:onclick 事件不触发

HTMLOptionElement: onclick event doesn't trigger

我想要一个 select 元素包含一个默认选项,该选项在 selected 时显示一个弹出窗口。所以我创建了 HTMLOptionElement 并向 onclick 事件侦听器添加了一个事件,但是当单击该选项时该事件不会触发。

这是我的代码:

const selectDefaultOption = new Option(".. show popup ...");
selectDefaultOption.addEventListener("mouseup", () => {
    // ... show pop up
});
document.querySelector("#select").appendChild(selectDefaultOption);

我做错了什么吗?或者不可能实现我想要的?

结论&解决方案

经过几次尝试,我得出的结论是,没有简单的解决方案可以简单地触发附加到 select 选项的事件。

但是,当特定选项被 selected 时,我设法实现了执行一个动作(尽管它不像我最初的意图那么优雅)。

解决方法:

const selectElement = document.querySelector("#select");

const placeholderOption = new Option("<< select option >>", "<< select option >>", true, true);
placeholderOption.style.display = "none"; // this option is never display in the selection and serves only as a placeholder
selectElement.add(placeholderOption, null);

const onclickOption = new Option("onclick option", "onclick option")
onclickOption.onclick = () => alert("onlick option clicked!");
selectElement.add(onclickOption, null);

let previousSelectedValue;
selectElement.onmouseenter = event => {
  previousSelectedValue = event.target.value;
  event.target.value = placeholderOption.value;
  event.target.onmouseleave = event => {
    event.target.value = previousSelectedValue;
  };
} 
selectElement.oninput = event => {    
  event.target.onmouseleave = undefined; // reset the onmouseleave so it doesn't change current value
  const selectedOption = event.target.selectedOptions[0];
  if (selectedOption.onclick){
    selectedOption.onclick(selectedOption.event); 
    event.target.value = previousSelectedValue; // you may assign placeholderOption.value
  }
};
<select id="select">
    <option>option#1</option>
    <option>option#2</option>
</select>

您可以将侦听器放在 select 元素上并检查值(而不是直接将侦听器放在选项元素上)

document.querySelector('select').addEventListener('change', e => {
  if (e.target.value === '2') console.log('The special option was chosen');
})
<select>
  <option value='1'>1</option>
  <option value='2'>Special</option>
  <option value='3'>3</option>
</select>

首先,我将 eventListener 添加到 select 容器中。作为触发器,我集中注意力。然后我使用您的代码创建一个新的选项元素。这个元素我分配了一个新的 eventListener 触发警报()。

所有浏览器的更新

在大多数浏览器上,已创建元素的选项标签上分配的 EventListener 将失败。这就是为什么将 EventListerner 绑定到 Select 标签是正确的。然后你可以通过值字段查看它是哪个字段。

const s = document.getElementById('select');
let isLoaded = false;

s.addEventListener('focus', () => {  
  if (! isLoaded) {
    const selectDefaultOption = new Option(".. show popup ...");    
    selectDefaultOption.setAttribute('value', "popup");
    s.appendChild(selectDefaultOption);
  }
  isLoaded = true;
});

function callPopUp(event) {
  let s = document.getElementById('select');
  if (s.value === 'popup') {
    alert('PopUp')
  }
}
select {
  width: 200px;
  background: gray;
  padding:10px;
}
<select id="select" onclick='callPopUp(event)'>
  <option value="123">123</option>  
  <option value="456">456</option>  
</select>

备注

与@Olafvolafka 一起,我们发现在大多数浏览器(Chrome、Opera)中,无法将事件成功绑定到选项标签/元素。没有事件被触发。只有在 Firefox 中才会触发事件。因此,我们必须使用变通方法。状态 01/2022。