JavaScript月历日期加载异常:仅首次选月生效,后续无响应
日期选择框二次点击月份无响应问题解决
问题根源
你的代码存在变量覆盖的核心问题:
- 先声明
var mes = document.getElementsByName("mes")存储所有月份单选框的NodeList - 但在
dias_mes函数内部,又将mes赋值为选中的月份数值(如1、2),直接覆盖了原本的NodeList对象 - 首次调用函数后,
mes变成数字,后续点击月份时,函数里的for (var i = 0; i < mes.length; i++)会因mes.length不存在(数字无length属性)终止执行,无法获取新选中的月份,自然不会更新日期
修复方案
- 重命名变量避免覆盖:将存储月份单选框的变量改为
mesElements,和函数内的选中月份值区分开 - 优化循环效率:找到选中的月份后直接跳出循环
- 补充闰年判断:原代码二月固定28天,新增闰年逻辑让日期更准确
修正后的完整代码
<form action="" method="get"> <div id="date_select"> <div id="mess_btns"> <input type="radio" name="mes" value="" style="display: none;" required> <div class="mes_cont"> <input type="radio" name="mes" id="mes1" value="1"> <label for="mes1">Ene</label> </div> <div class="mes_cont"> <input type="radio" name="mes" id="mes2" value="2"> <label for="mes2">Feb</label> </div> <div class="mes_cont"> <input type="radio" name="mes" id="mes3" value="3"> <label for="mes3">Mar</label> </div> <div class="mes_cont"> <input type="radio" name="mes" id="mes4" value="4"> <label for="mes4">Abr</label> </div> <div class="mes_cont"> <input type="radio" name="mes" id="mes5" value="5"> <label for="mes5">May</label> </div> <div class="mes_cont"> <input type="radio" name="mes" id="mes6" value="6"> <label for="mes6">Jun</label> </div> <div class="mes_cont"> <input type="radio" name="mes" id="mes7" value="7"> <label for="mes7">Jul</label> </div> <div class="mes_cont"> <input type="radio" name="mes" id="mes8" value="8"> <label for="mes8">Ago</label> </div> <div class="mes_cont"> <input type="radio" name="mes" id="mes9" value="9"> <label for="mes9">Sep</label> </div> <div class="mes_cont"> <input type="radio" name="mes" id="mes10" value="10"> <label for="mes10">Oct</label> </div> <div class="mes_cont"> <input type="radio" name="mes" id="mes11" value="11"> <label for="mes11">Nov</label> </div> <div class="mes_cont"> <input type="radio" name="mes" id="mes12" value="12"> <label for="mes12">Dic</label> </div> </div> <div id="dias_btns"> </div> <div id="anyos_cont"> <select class="year_select" name="ano" id="ano"> </select> </div> </div> <input type="submit" value="Enviar"> </form> <script> var meses = document.getElementsByName("mes"); for (var i = 0; i < meses.length; i++) { meses[i].onclick = function() { valor = this.value; console.log(valor); }; } var year = new Date().getFullYear(); var select = document.getElementById("ano"); for (var i = year - 16; i > year - 56; i--) { var option = document.createElement("option"); option.value = i; option.text = i; select.appendChild(option); } select.style.width = "200px"; select.style.height = "40px"; select.style.fontSize = "1.5rem"; select.style.textAlign = "center"; select.style.textAlignLast = "center"; var dias_cont = document.getElementById("dias_btns"); var dias = 31; var mesElements = document.getElementsByName("mes"); // 重命名变量避免覆盖 function dias_mes() { var selectedMes = 0; // 单独存储选中的月份值 for (var i = 0; i < mesElements.length; i++) { if (mesElements[i].checked) { selectedMes = mesElements[i].value; break; // 找到选中项后直接跳出循环,提升效率 } } // 处理闰年二月的情况 var selectedYear = document.getElementById("ano").value; if (selectedMes == 1 || selectedMes == 3 || selectedMes == 5 || selectedMes == 7 || selectedMes == 8 || selectedMes == 10 || selectedMes == 12) { dias = 31; } else if (selectedMes == 4 || selectedMes == 6 || selectedMes == 9 || selectedMes == 11) { dias = 30; } else if (selectedMes == 2) { // 闰年判断:能被4整除但不能被100整除,或能被400整除 dias = (selectedYear % 4 === 0 && selectedYear % 100 !== 0) || selectedYear % 400 === 0 ? 29 : 28; } dias_cont.innerHTML = ""; for (var i = 1; i <= dias; i++) { var div = document.createElement("div"); div.className = "dias_cont"; var input = document.createElement("input"); input.type = "radio"; input.name = "dia"; input.id = "dia" + i; input.value = i; var label = document.createElement("label"); label.htmlFor = "dia" + i; label.innerHTML = i; div.appendChild(input); div.appendChild(label); dias_cont.appendChild(div); } } for (var i = 0; i < mesElements.length; i++) { mesElements[i].onclick = function() { dias_mes(); }; } dias_mes(); </script> <style> #mess_btns { position: relative; margin: 0 auto; display: flex; gap: 2px; width: 260px; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: center; padding: 10px; } .mes_cont label { width: 78px; height: 50px; background-color: #fdfdfd; display: flex; flex-direction: row; align-items: center; justify-content: center; border-radius: 6px; border: 1px solid #e2e4ea; color: #818181; cursor: pointer; transition: background-color 200ms ease; } .mes_cont { display: inline-block; } .mes_cont>input[type="radio"] { display: none; } .mes_cont input[type="radio"]:checked+label { background-color: #ffaf00; color: #fff; text-shadow: -1px 1px 0 #c47b1a; border: 3px solid #ff9800; } #dias_btns { position: relative; margin: 0 auto; display: flex; gap: 0.09rem; width: 260px; flex-direction: row; align-items: center; justify-content: flex-start; padding: 10px; flex-wrap: wrap; border-radius: 0 0 6px 6px; } .dias_cont label { width: 33px; height: 32px; background-color: #fdfdfd; display: flex; flex-direction: row; align-items: center; justify-content: center; border-radius: 6px; border: 1px solid #e2e4ea; color: #818181; cursor: pointer; transition: background-color 200ms ease; } .dias_cont { display: inline-block; } .dias_cont>input[type="radio"] { display: none; } .dias_cont input[type="radio"]:checked+label { background-color: #ffaf00; color: #fff; text-shadow: -1px 1px 0 #c47b1a; border: 3px solid #ff9800; } input[type="checkbox"].optin_chkbx { width: 24px; height: 24px; transform: translate(16px, 7px); accent-color: #5693a1; box-shadow: 0 0 0 1px #e4e4e4 inset, 0 0 0 1px #e4e4e4; -webkit-appearance: none; border-radius: 4px; } input[type="checkbox"].optin_chkbx:checked { background-color: #1e448c; color: #fff; } </style>
内容的提问来源于stack exchange,提问作者Samuel Ramzan
相关产品推荐
相关产品推荐

