All the answers so far are pointing that OP might be doing something wrong by not creating select dynamically. But we don't know his requirements.
Also everybody already explained document.write will write on you entire document thus deleting everything, you don't want that.
document.write --> https://developer.mozilla.org/en-US/docs/Web/API/Document/write
appendChild should be used but you wanted a string and appendChild expect Node not string.
appendChild --> https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild
node --> https://developer.mozilla.org/en-US/docs/Web/API/Node
So the only way to solve this is by using innerHTML and summing up inner Html by adding new ones.
Or by creating node from sting, which requires some more logic, see here --> Creating a new DOM element from an HTML string using built-in DOM methods or prototype
innerHTML --> https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
const selectTamplate = (selectId, onChangeCallbackName) => {
return `
<select name='test' id='mySelect${selectId}' style='font-size:10px' onchange='${onChangeCallbackName}()'>
<option value='zeroPoint'>0</option>
<option value='halfPoint'>1/2</option>
<option value='onePoint'>1</option>
</select>
`
};
const appendStringHtml = (elementTargetHtml, elemenAppend) => {
elemenAppend.innerHTML += elementTargetHtml;
}
const doSomethingOnChange = () => {
console.log('I am the KING!');
};
const placeToAppend = document.querySelector('.append-selects-here');
const buttonAppender = document.querySelector('.btn-append');
let selectID = 1;
buttonAppender.addEventListener('click', ()=>{
const selectHTML = selectTamplate(selectID, 'doSomethingOnChange');
appendStringHtml(selectHTML, placeToAppend);
selectID ++;
});
<button class="btn-append">Add Selects</button>
<div class="append-selects-here"></div>
see the working code here --> https://codepen.io/nikolamitic/pen/PEpEbj
I used template string so that interpolation is possible, little bit more clear. And separate the logic while still keeping yours.