#javascript #html #css
Вопрос:
У меня есть таблица, содержащая столбец даты. В этом столбце указаны даты из прошлого в будущее, включая текущее время с интервалами примерно в 7 минут (оно может измениться). Мне нужно окрасить строку, имеющую текущее значение, зеленым цветом и переместить зеленый цвет в следующую строку, когда будет достигнуто следующее время. Можно ли прослушать значение времени и изменить стиль по строкам? Я мог бы раскрасить текущее значение, но со временем стиль не перемещается в следующую строку, так как код выполняется один раз при загрузке страницы.
Вот моя попытка кода: я использую vue so в части таблицы HTML:
<tbody v-for='row in rows' :key='row.id'>
<tr :style="{'background-color': dateFormat(row.date) ?'green' :'' }">
...
</tr>
</tbody>
и в методах:
dateFormat(d) {
const time = new Date(d);
const cc = new Date();
if (time.getMinutes() === cc.getMinutes()) return true;
return false;
}
Любая помощь будет оценена по достоинству!
Заранее спасибо.
Комментарии:
1. Где ваш код попытки?
2. Видишь developer.mozilla.org/en-US/docs/Web/API/… , и если вы застряли при попытке решить свою задачу, задайте вопрос.
3. Я добавил свою попытку кода @StackSlave
4. Вам понадобится какой-то тест на время. Возможно, внутри
setInterval
или на каком-то Мероприятии.5. @StackSlave это именно то, что я ищу. событие, которое прослушивает значение ячейки!
Ответ №1:
Там не так много информации о том, в какую таблицу вы хотите интегрировать действие. Вы можете применить следующие инструкции, чтобы достичь желаемого.
Сделайте «модель» задачи, сначала прочитайте даты, когда активная строка должна измениться на массив JS ( data
в примере кода). Удобно также включать строки таблицы в этот массив, что экономит некоторое время, когда вам не нужно запрашивать DOM, чтобы найти строку для выделения. Затем создайте несколько переменных для хранения некоторой информации о состоянии задачи ( current
, next
). Эта информация используется для контроля состояния. Наконец, создайте таймер, который запускается, когда нужно дождаться следующей даты. Рассчитайте задержку на основе значений, сохраненных в модели. Что-то вроде этого:
// Fill the dates (for the example only)
const rows = Array.from(document.querySelector('#traced').rows);
fillDates(new Date(), 5); // constant 5 = increase time [second]
// A date can be passed to Date constructor as an acceptable string too
// Creates the timer
(function() {
const tbody = document.querySelector('#traced'),
rows = Array.from(tbody.rows),
data = rows.map(row => {
const time = new Date(row.cells[1].textContent).getTime();
// The constant 1 above is the date column number of the table
return {row, time};
});
let now = Date.now(),
last = data.length - 1,
next = data.findIndex(row => row.time > now),
current = Math.max(-1, next - 1);
if (now > data[last].time) {
// All the dates are in the past, no need for a timer
data[last].row.classList.add('active');
return;
}
// Updates row highlighting and counters, the timed function
function activateRow() {
// Update highlights
if (current > 0) {
// Remove the current highlight
data[current - 1].row.classList.remove('active');
}
if (current > -1 amp;amp; next) {
// Highlight the current row
data[current].row.classList.add('active');
}
// Set the timer if needed
if (next > last) {return;} // Quit, no more dates to await
const delay = data[next].time - Date.now();
window.setTimeout(activateRow, delay);
// Update counters
current = 1;
next = 1;
}
activateRow();
}());
// Emulates the server-side dynamic table filling (for the example only)
function fillDates(base, gap = 15000) {
if (gap < 1000) {
gap *= 1000;
}
gap = Math.floor(Math.random() * 3000);
const zone = new Date().getTimezoneOffset(),
date = new Date(base).getTime() - zone * 60000;
rows.forEach((row, index) => {
const dte = new Date(date gap * index).toISOString(),
end = dte.length - 5;
row.lastElementChild.textContent = dte.substring(0, end);
});
}
.active {
background: green;
}
<table>
<tbody id="traced">
<tr><td>Date 1</td><td></td></tr>
<tr><td>Date 2</td><td></td></tr>
<tr><td>Date 3</td><td></td></tr>
<tr><td>Date 4</td><td></td></tr>
<tr><td>Date 5</td><td></td></tr>
<tr><td>Date 6</td><td></td></tr>
</tbody>
</table>
Когда вы интегрируете пример в свой собственный код, включите в свой JS-код только IIFE, остальные части фрагмента предназначены для того, чтобы можно было разумно запускать код в часовом поясе посетителя StackSnippet. Конечно, вы также должны определить active
класс в своем CSS. Вы также не должны включать стиль активной строки на сервере, фрагмент JS позаботится о выделении.
В зависимости от формата даты в таблице вам также может потребоваться отредактировать код в соответствии с используемым форматом и даже внести изменения в фактические даты, поскольку в зависимости от часового пояса посетителя даты, которые вы добавляете на сервере, могут сильно отличаться в каком-либо другом часовом поясе, и автоматический маркер не будет работать.
Там также есть jsFiddle, с которым можно поиграть.
Комментарии:
1. похоже, именно то, что мне нужно, большое спасибо @Teemu, однако я не смог запустить его в своем компоненте Vue. Я добавил вашу функцию IIFE в mounted() в vue, но, к сожалению, она все еще не работает! Я занимаюсь этим!
2. Это не обязательно должен быть IIFE, вы можете сделать его объявленной функцией, или добавить функцию в качестве метода в объект, или назначить ее переменной и т. Д., Просто не забудьте ее вызвать. К сожалению, я не знаком с vue, поэтому не могу помочь вам с интеграцией.
3. В этом случае было бы много течений, много будущего и прошлого! для каждой группы
4. @Abood Если я правильно понял ваше описание (таблица не упорядочена по датам), вы можете отсортировать
data
массив по датам в JS после его заполнения. Что-то вродеdata.sort((a, b) => return a.time - b.time)
.5. Я вижу, спасибо за совет, это мой самый первый вопрос, поэтому мне нужно некоторое время, чтобы привыкнуть к нему и узнать правила игры здесь. спасибо за ваш совет 🙂