Como já disseram, o problema é que o JS está tentando buscar os elementos HTML antes deles serem carregados e parseados.
Uma alternativa é carregar isso só depois do HTML, usando DOMContentLoaded
:
// declara as variáveis
let num, lista, res, valores = [];
// depois que o HTML é carregado, atribui as variáveis aos seus respectivos elementos
document.addEventListener('DOMContentLoaded', function () {
num = document.querySelector('input#fnum');
lista = document.querySelector('select#flista');
res = document.querySelector('div#res');
});
// definição das funções continua aqui
function isnumero(n) {
etc...
Segundo a documentação, o evento DOMContentLoaded
dispara somente depois que o HTML foi completamente parseado, ou seja, ali já é garantido que os elementos existirão. Repare que valores
eu posso inicializar antes, já que seu valor não depende do conteúdo da página.
E em vez de converter para número, pode usar valueAsNumber
, que já retorna o valor como um número. Além disso, toda vez que vc tem algo assim:
if (condicao) {
return true;
} else {
return false;
}
Pode trocar por:
return condicao;
Ou seja, suas funções poderiam ser:
function isnumero(n) {
return n >= 1 && n <= 100;
}
function inlista(n, l) {
return l.indexOf(n) != -1;
}
function adicionar() {
if (isnumero(num.valueAsNumber) && !inlista(num.valueAsNumber, valores)) {
alert(`tudo ok`);
} else {
alert(`erro`);
}
}
E a segunda função também poderia ser:
function inlista(n, l) {
return l.includes(n);
}
Se bem que nesse caso, não sei nem se precisaria dessa função, poderia ser apenas:
function adicionar() {
if (isnumero(num.valueAsNumber) && !valores.includes(num.valueAsNumber)) {
alert(`tudo ok`);
} else {
alert(`erro`);
}
}