Ich habe das jetzt auf Custom-Elemente und connectedCallback umgestellt.
Funktioniert einwandfrei und das JS ist sogar ein wenig einfacher geworden.
Cool was man so alles machen und lernen kann.
HTML
<!DOCTYPE html>
<html>
<head>
<title>Stylable Select With Radiobuttons</title>
<style>
/* Begin stylable select */
stylable-select {
position: relative;
display: inline-block;
font-family: Arial, Helvetica, sans-serif;
}
stylable-select stylable-select-options {
display: flex;
flex-direction: column;
position: absolute;
top: 100%;
left: 0;
width: 100%;
background-color: white;
}
stylable-select stylable-select-options.hidden {
display: none;
}
stylable-select stylable-select-out::after {
content: '▼';
}
stylable-select stylable-select-out {
min-width: 8em;
display: flex;
justify-content: space-between;
border: 1px solid blue;
padding-left: 0.2em;
}
stylable-select stylable-select-options label {
border: 1px solid lightblue;
}
stylable-select label.selected {
background-color: lightgray;
}
/* End stylable select */
/* Custom styles: */
stylable-select stylable-select-options label {
border: 2px solid darkgreen;
border-radius: 2px;
background-color: lightgreen;
}
stylable-select stylable-select-options label::before {
content: '•';
margin-left: 0.2em;
margin-right: 0.2em;
}
</style>
<script>
class StylableSelect extends HTMLElement {
constructor() {
// Always call super first in constructor
super();
}
connectedCallback() {
window.addEventListener('click', event => {
// Prüfen ob das geklickte Element ein Kind dieses Elementes ist */
const
select = event.target.closest('stylable-select');
if (select == this) {
/* Wurde der Kopf des Selects geklickt? */
if (event.target.tagName.toLowerCase() == 'stylable-select-out') {
/* Sichtbarkeit der Optionen umschalten */
this.querySelector('stylable-select-options')
.classList.toggle('hidden');
}
// Prüfen ob das geklickte Element eine Option ist
// (nur die Optionen haben ein Label)
const
lbl = event.target.closest('label');
if (lbl) {
// Klasse "selected" löschen bei dem Label,
// das sie bisher hatte
const
selectedLabel = this.querySelector('label.selected');
if (selectedLabel) selectedLabel.classList.remove('selected');
// Beim geklickten Label die Klasse "selected" hinzu fügen
lbl.classList.add('selected');
// Wert und Text in die Ausgabefelder übertragen
this.querySelector('input[name]').value
= this.querySelector('label.selected input').value;
this.querySelector('stylable-select-out span').textContent
= this.querySelector('label.selected').textContent;
this.querySelector('stylable-select-options').classList.add('hidden');
}
}
});
}
getValueAndText() {
const
out = this.querySelector('stylable-select-out'),
text = out.querySelector('span').textContent,
value = out.querySelector('input').value;
return { value: value, text: text };
}
}
customElements.define("stylable-select", StylableSelect);
</script>
</head>
<body>
<button id="btn-out-val-1">Output Value 1</button>
<button id="btn-out-val-2">Output Value 1</button>
<!-- Begin stylable select -->
<!-- Modify ID -->
<stylable-select id="select1">
<stylable-select-out>
<span>Select an option</span>
<!-- Modify name of input -->
<input name="select1" value="" hidden>
</stylable-select-out>
<stylable-select-options class="hidden">
<!-- Modify options or labels containing radio buttons -->
<label><input type="radio" value="opt11" hidden>Option 1-1</label>
<label><input type="radio" value="opt12" hidden>Option 1-2</label>
<label><input type="radio" value="opt13" hidden>Option 1-3</label>
<label><input type="radio" value="opt14" hidden>Option 1-4</label>
</stylable-select-options>
</stylable-select>
<!-- End stylable select -->
<!-- Begin stylable select -->
<!-- Modify ID -->
<stylable-select id="select2">
<stylable-select-out>
<span>Select an option</span>
<!-- Modify name of input -->
<input name="select2" value="" hidden>
</stylable-select-out>
<stylable-select-options class="hidden">
<!-- Modify options or labels containing radio buttons -->
<label><input type="radio" value="opt21" hidden>Option 2-1</label>
<label><input type="radio" value="opt22" hidden>Option 2-2</label>
<label><input type="radio" value="opt23" hidden>Option 2-3</label>
<label><input type="radio" value="opt24" hidden>Option 2-4</label>
</stylable-select-options>
</stylable-select>
<!-- End stylable select -->
<script>
document.getElementById('btn-out-val-1').addEventListener('click', event => {
console.log(document.getElementById('select1').getValueAndText());
});
document.getElementById('btn-out-val-2').addEventListener('click', event => {
console.log(document.getElementById('select2').getValueAndText());
});
</script>
</body>
</html>
Alles anzeigen