尝试基于小时动态颜色代码行时出现问题



我正在做一个JS项目,在这个项目中我创建了一个每日时间表,每个小时都应该根据过去、现在或未来进行颜色编码。

时间表从上午9点到下午5点。目前,它正在将future类应用于每个块,所以每一行都显示为绿色。相反,假设是上午11点,那么上午11点的行在当前时间将突出显示为红色,上午11点之前的行将为灰色或透明,未来的小时将为绿色。

我为我的每个小时块设置了Id,以便解析并与当前小时进行比较,但由于某种原因,它不起作用。我已经在CSS中为过去、现在和未来设置了类。

var blocks = document.getElementsByClassName("description");
var hourBlock = parseInt(moment().format('H'));

Array.from(blocks).forEach(description => {
let idString = description.id, rowHour;

if (idString) {
rowHour = parseInt(idString);
}

if (rowHour) {
if (hourBlock === rowHour) {
$(".description").addClass("present")
} else if (hourBlock < rowHour) {
$(".description").addClass("past")
} else {
$(".description").addClass("future");
}
}
});

问题是因为在循环中,您要更新所有.description元素的类,而不是forEach循环中的类。

为了解决这个问题,并使代码更加简洁,您可以将一个函数传递给jQuery的addClass()方法,该方法将针对集合中的每个元素单独进行评估。在这个函数中,您可以对照当前小时(不需要MomentJS(检查元素的id,并设置适当的类。试试这个:

// let nowHour = (new Date()).getHours();
let nowHour = 13; // hard-coding value for this demo
$('.description').addClass(function() {
return +this.id === nowHour ? 'present' : +this.id < nowHour ? 'past' : 'future'; 
});
.present { background-color: #C00; }
.past { background-color: #CCC; }
.future { background-color: #0C0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="description" id="9">9am</div>
<div class="description" id="10">10am</div>
<div class="description" id="11">11am</div>
<div class="description" id="12">12pm</div>
<div class="description" id="13">1pm</div>
<div class="description" id="14">2pm</div>
<div class="description" id="15">3pm</div>
<div class="description" id="16">4pm</div>
<div class="description" id="17">5pm</div>

任何时候调用这样的代码:

$(".description").addClass("past");

它将查询所有具有类"description"的元素,因为将该类设置为过去。您想要做的只是设置循环中要检查的元素的类。

由于您使用的是jquery,我们不需要getElementsByClassName('description'(,因为它可以翻译为$('.description'(.

// using jquery's each to loop through the collection
$('.description').each((idx, elt) => {
$(elt).removeClass(); // no params to clear ALL classes from element
// put whatever logic you want to analyze the element (elt)
$(elt).addClass("whateverClassYouWant");
// add the description back on, or don't remove it and instead removeClass('specificClass') for each past/present/future
$(elt).addClass("description");
});

在您的代码中,您从不删除类,只是不断添加它们。您为元素分配了正确的类,这是合理的,但由于您从未删除不正确的类(或者所有元素都有所有的类!(,因此CSS必须根据内部优先级选择哪种颜色覆盖其他颜色。

您不希望有任何歧义-每个项应该只有它需要的1个类,因此不带参数的.removeClass((调用将在您将所需的类添加回.之前删除所有类

HTML没有发布,所以我使用了最合适的标签:<table>及其子标签。只需将所有<th>收集到一个数组中,然后对它们进行迭代,回调只是一个if/if else流控制语句,用于确定className的分配。时间是由实际时间决定的。

let t = new Date()
let hour = t.getHours();
const cols = [...document.querySelectorAll('th')];
cols.forEach(h => h.className = '');
cols.forEach((h, i) => {
if (i + 9 < hour) {
h.className = 'past';
} else if (i + 9 > hour) {
h.className = 'future';
} else {
h.className = 'present';
}
});
.past {
background: grey
}
.future {
background: green
}
.present {
background: red
}
<table>
<thead>
<tr>
<th>9AM</th>
<th>10AM</th>
<th>11AM</th>
<th>12PM</th>
<th>1PM</th>
<th>2PM</th>
<th>3PM</th>
<th>4PM</th>
<th>5PM</th>
</tr>
</thead>
<tbody>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>

最新更新