在两个不同的选择/选项中迭代数月和数天

时间:2017-01-12 15:45:12

标签: javascript html-select

基本上,我试图让一个选择元素迭代一年中的十二个月,并根据显示的月份,另一个选择元素显示该月份的天数。 即如果在第一个选择元素中选择了1月,则第二个选择元素将显示第1天到第30天。如果选择11月,则第二个选择元素将显示第1天到第31天,依此类推。

HTML:

<select type="text" id="month"></select>

<label>Days:</label>
<select type="text" id="day" onchange="checkMonth(this.value)"></select>

变量:

var months  =["JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"];
var month   = document.getElementById('month');
var day     = document.getElementById('day');

JavaScript的:

for(var index in month) {
    month.options[month.options.length] = new Option(month[index], index);
}

if (month.val() === months[3] || months[5] || months[8] || months[10]){
    var numOfDays = 30;

    for(var i = 1; i <= numOfDays; i++) {
        for(i in day) {
            day.options[day.options.length] = new Option(day[i], i);
        }
    }
}
else if (month.val() === months[0] || months[2] || months[4] ||  months[6] || months[7] || months[9] || months[11]) {
    var numOfDays = 31;

    for(var i = 1; i <= numOfDays; i++) {
        for(i in day) {
            day.options[day.options.length] = new Option(day[i], i);
        }
    }
}
else {
    var numOfDays = 28;

    for(var i = 1; i <= numOfDays; i++) {
        for(i in day) {
            day.options[day.options.length] = new Option(day[i], i);
        }
    }
}

问题:我该怎么做,我的代码错了?

2 个答案:

答案 0 :(得分:0)

首先,您的javascript代码缺少任何事件侦听器。这意味着你的javascript只执行一次,然后它就是死代码。当选中其中一个复选框时,系统无法自动猜测您是否希望运行某些代码。你必须指定它。尝试在onload状态下运行代码会导致错误。

所以第1步,就是将日期选择框的更新功能包装在它自己的功能中。我们将其称为function updateDays(),这应该在您的第一个if语句之前添加。记住括号!

第2步是修复月份选择框的人口。这几个月永远不会改变,所以我只是简单地将它们编码到HTML中,但为了不更改代码而不是必要的,这就是你需要做的:

  • 让我们先看一下for(var index in month)。我猜你想要遍历月份名称数组,并将它们作为选项添加到选择框中。在这里,您似乎已将monthmonths混淆了。替换变量名称,在下拉列表中为您提供12个选项,但到目前为止它们没有内容。但它们的值为0-11,在找到日期时似乎与您的预期值相符。
  • 再一次,您似乎已将monthmonths混淆了。更改变量名称,现在成功填充月份选择:

错误的行:

month.options[month.options.length] = new Option(month[index], index);

正确的行:

month.options[month.options.length] = new Option(months[index], index);

步骤3是让系统知道每当月份选择发生变化时更新日期选择框。为此,我们必须添加一个侦听器函数,在本例中是一个更改侦听器:

month.addEventListener('change', updateDays);

当然,我们希望updateDays在开头运行一次,当下拉菜单设置为1月时,我们也会在这里调用一次:

updateDays();

第4步是修复你的updateDays() - 函数。有几点你应该改进,但我会先谈谈你所犯的明显错误:

if (month.val() === months[3] || months[5] || months[8] || months[10]){

首先,我认为只需调用month.val()即可检索该值。其次,当您使用OR运算符||时,您应该知道javascript不会以这种方式运行。要实现您想要的,您必须在每个OR运算符之间使用相等运算符的两侧。样品:

value === check1 || check2 || check3 || check4 //wrong
value === check1 || value === check2 || value === check3 //correct

您的代码只检查一次该值是否为&#34; APRIL&#34;。如果它不是,它只是检查&#34; JUNE&#34;是真的。 Javascript的设计使得在检查这样的字符串时,如果它存在则返回true。换句话说,你的当前功能总是会返回30,因为字符串&#34; JUNE&#34;永远存在。

步骤5是修复填充日期下拉的功能。我必须承认,我并不完全明白你在那里做什么,所以我重写了整个事情。最后,这是您的javascript代码的样子:

var months = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"];
var month = document.getElementById('month');
var day = document.getElementById('day');

for (var index in months) {
  month.options[month.options.length] = new Option(months[index], index);
}

month.addEventListener('change', updateDays);

updateDays();

function updateDays() {
  var month = document.getElementById('month');
  var value = month.options[month.selectedIndex].text;
  if (value === months[3] || value === months[5] || value === months[8] || value === months[10]) {
    var numOfDays = 30;
  } else if (value === months[0] || value === months[2] || value === months[4] || value === months[6] || value === months[7] || value === months[9] || value === months[11]) {
    var numOfDays = 31;
  } else {
    var numOfDays = 28;
  }

  for (var i = 1; i <= numOfDays; i++) {
    day.options[day.options.length] = new Option(i, i);
  }
}

检查一下,看看它的实际效果:https://jsfiddle.net/o6n6k1s8/

我作为开发人员的热门提示是了解有关如何在应用程序中调试错误的更多信息。尽管存在很多不同的错误,但大多数都是非常小的错误,而且你的总体思路是正确的。如果您学习如何找到自己的特定错误,那么您将成为一名优秀的程序员。谷歌主题,如chrome inspector或mozilla firebug。

祝你好运

答案 1 :(得分:0)

就其价值而言,我通过比较索引对其进行了简化。

(为现代浏览器编写)

我已经把所有的代码都放进去了,如果它让人困惑,我会去掉那些不适用的。 只是觉得它可能有用。

// Populate the Date Search Select Inputs
const getWeek = () => {
  let now = new Date(), yearBegin = new Date(now.getFullYear(), 0)
  return Math.ceil((((now.setHours(0,0,0,0) - yearBegin) / 86400000)-1)/7)
}

const dayfield = document.getElementById('searchDay')
const weekfield = document.getElementById('searchWeek')
const monthfield = document.getElementById('searchMonth')
const yearfield = document.getElementById('searchYear')
const today = new Date()
const months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];

let numOfDays = 0
const updateDays = (value) => {
  if ([3,5,8,10].includes(value)) numOfDays = 30
  else if ([0,2,4,6,7,9,11].includes(value)) numOfDays = 31 
  else numOfDays = 28
};updateDays(months[today.getMonth()])

monthfield.addEventListener('change', () => {
  updateDays(monthfield.selectedIndex) // Update days compares the Months array index, with the select index.
  while (dayfield.options.length > 0) dayfield.remove(0)
  for ( let d = 1; d <= numOfDays; d++ ) dayfield.appendChild(new Option(d, d))
  dayfield.value = today.getDate()
})
dateBoxesPopulate = () => {
  
  for ( let y = 2000; y <= 2050; y++ ) yearfield.appendChild(new Option(y, y))
  yearfield.value = today.getFullYear()

  for ( let m = 0; m < 12; m++ ) monthfield.appendChild(new Option(months[m], months[m]))
  monthfield.value = months[today.getMonth()]

  for ( let w = 0; w <= 53; w++ ) weekfield.appendChild(new Option(w, w)) // Week One Starts On The First Sunday.
  weekfield.value = getWeek()

  for ( let d = 1; d <= numOfDays; d++ ) dayfield.appendChild(new Option(d, d))
  dayfield.value = today.getDate()
}