问题
What I want to know
- How to also apply the constructor to
DOMs.selectTimes
. - More efficient ways to clean up my code
What my code is for
I made a script which creates option elements for HTML forms dynamically. I could apply birthYear/birthMonth/birthDay
to a constructor. But I can't do it for selectTimes
. How can I do it? OR are there any more efficient ways?
Here is my code
(function() {
/* Fetch DOMs */
const DOMs = {
selectYear: document.querySelector('#select-birthyear'),
selectMonth: document.querySelector('#select-birthmonth'),
selectDay: document.querySelector('#select-birthday'),
selectTimes: document.querySelectorAll('.select-time'),
selects: document.querySelectorAll('.select')
};
/* Create options */
function createOptions() {
let html;
// Create time options
let arrTimes = [
'10:00',
'10:30',
'11:00',
'11:30',
'12:00',
'12:30',
'13:00',
'13:30',
'14:00',
'14:30',
'15:00',
'15:30',
'16:00',
'16:30',
'17:00',
'17:30',
'18:00'
];
DOMs.selectTimes.forEach(selectTime => {
for (let i = 0; i < arrTimes.length; i++) {
html = `<option value="${arrTimes[i]}">${arrTimes[i]}</option>`;
selectTime.insertAdjacentHTML('beforeend', html);
}
});
// Constructor for year/month/day
function OptionLoop(DOM, start, end, unit) {
this.DOM = DOM;
this.start = start;
this.end = end;
this.unit = unit;
}
OptionLoop.prototype.setOptions = function() {
for (let i = this.start; i <= this.end; i++) {
html = `<option value="${i}${this.unit}">${i}${this.unit}</option>`;
this.DOM.insertAdjacentHTML('beforeend', html);
}
};
// Set year/month/day options
const birthYear = new OptionLoop(DOMs.selectYear, 1960, 2005, '年');
const birthMonth = new OptionLoop(DOMs.selectMonth, 1, 12, '月');
const birthday = new OptionLoop(DOMs.selectDay, 1, 31, '日');
// Create year/month/day options
birthYear.setOptions();
birthMonth.setOptions();
birthday.setOptions();
}
/* Initialize */
function init() {
let isEmpty = false
// Fetch how many options each <select> has
DOMs.selects.forEach(select => {
if (select.childElementCount <= 1) {
return isEmpty = !isEmpty;
}
});
// Implement when each <select> has just one <option>
if (isEmpty) {
createOptions();
}
}
/* Implement the function when the window is loaded */
window.addEventListener('load', init);
})();
<select class="select select-time">
<option value="" disabled selected>START TIME1</option>
</select>
<select class="select select-time">
<option value="" disabled selected>END TIME1</option>
</select>
<select class="select select-time">
<option value="" disabled selected>START TIME2</option>
</select>
<select class="select select-time">
<option value="" disabled selected>END TIME2</option>
</select>
<select id="select-birthyear" class="select">
<option value="" disabled selected>YEAR</option>
</select>
<select id="select-birthmonth" class="select">
<option value="" disabled selected>MONTH</option>
</select>
<select id="select-birthday" class="select">
<option value="" disabled selected>DAY</option>
</select>
回答1:
You can simply use custom Elments
https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements
class myTime extends HTMLSelectElement {
constructor() {
super()
this.OptTimes = [ '10:00', '10:30', '11:00', '11:30', '12:00', '12:30',
'13:00', '13:30', '14:00', '14:30', '15:00', '15:30',
'16:00', '16:30', '17:00', '17:30', '18:00' ]
}
connectedCallback() {
if (!this.dataset.range) {
for (let tim of this.OptTimes ) {
this.add(new Option(tim, tim))
}
}
else {
let [start, end, unit] = this.dataset.range.split(' ')
for(let i=start; i<=end; i++) {
this.add(new Option(`${i} ${unit}`,`${i} ${unit}`))
}
}
}
//disconnectedCallback() {}
}
customElements.define('my-time', myTime, {extends: 'select'})
<select is="my-time">
<option value="" disabled selected>START TIME1</option>
</select>
<select is="my-time">
<option value="" disabled selected>END TIME1</option>
</select>
<select is="my-time" data-range="1960 2005 年">
<option value="" disabled selected>YEAR</option>
</select>
<select is="my-time" data-range="1 12 月">
<option value="" disabled selected>MONTH</option>
</select>
<select is="my-time" data-range="1 31 日">
<option value="" disabled selected>DAY</option>
</select>
来源:https://stackoverflow.com/questions/60573934/create-options-with-constructor-javascript