Chcę, aby zaznaczony element zawierał jedną domyślną opcję, która po wybraniu wyświetla wyskakujące okienko. Stworzyłem więc HTMLOptionElement i dodałem zdarzenie do detektora zdarzeń onclick, ale zdarzenie nie jest wyzwalane po kliknięciu opcji.
Oto mój kod:
const selectDefaultOption = new Option(".. show popup ...");
selectDefaultOption.addEventListener("mouseup", () => {
// ... show pop up
});
document.querySelector("#select").appendChild(selectDefaultOption);
Czy robię coś źle? A może nie da się osiągnąć tego, do czego się staram?
Wnioski i rozwiązanie
Po kilku próbach doszedłem do wniosku, że nie ma zgrabnego rozwiązania, aby po prostu wywołać zdarzenie dołączone do wybranej opcji.
Udało mi się jednak osiągnąć wykonanie akcji, gdy wybrana jest konkretna opcja (choć nie jest to tak eleganckie, jak początkowo zamierzałem).
Rozwiązanie:
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>
3 odpowiedzi
Najpierw dodaję eventListener do wybranego kontenera. Jako wyzwalacz skupiłem się. Następnie używam Twojego kodu, aby utworzyć nowy element opcji. Do tego elementu przypisuję nowy eventListener, który wyzwala alert().
Aktualizacja dla wszystkich przeglądarek
Przypisanie EventListener do tagów opcji w utworzonym elemencie zakończy się niepowodzeniem w większości przeglądarek. Dlatego dobrze jest powiązać EventListerner z Select Tag. Następnie możesz sprawdzić, które to jest pole za pomocą pola wartości.
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>
Uwaga
Wraz z @Olafvolafka dowiedzieliśmy się, że w większości przeglądarek (Chrome, Opera) nie jest możliwe pomyślne powiązanie zdarzenia z tagiem/elementem opcji. Żadne zdarzenie nie zostało wywołane. Tylko w Firefoksie zostało wyzwolone zdarzenie. Dlatego musimy pracować z obejściem. Stan 01/2022.
Należy umieścić detektor na elemencie select i sprawdzić wartość (zamiast umieszczać detektor bezpośrednio na elemencie opcji)
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>
Twój kod działa. z mouseup
Zdarzenie mouseup jest uruchamiane na elemencie, gdy przycisk urządzenia wskazującego (takiego jak mysz lub gładzik) zostanie zwolniony, gdy wskaźnik znajduje się w nim.
https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseup_event
const selectDefaultOption = new Option(".. show popup ...");
selectDefaultOption.addEventListener("mouseup", () => {
alert()
});
document.querySelector("#select").appendChild(selectDefaultOption);
option {
width: 200px;
background: gray;
}
<div id="select">
<option>123</option>
</select>