как изменить стиль строки таблицы в зависимости от значения метки времени ячейки

#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. Я вижу, спасибо за совет, это мой самый первый вопрос, поэтому мне нужно некоторое время, чтобы привыкнуть к нему и узнать правила игры здесь. спасибо за ваш совет 🙂