如何使用 Class 而不是 ID

How to Use Class Instead of ID

我有这个问题的代码 How To Create Multiple CountDown Timers In The Same Page Using Javascript?。我不是 JavaScript 专家,所以如果有人可以帮助我使用 class 而不是 ID 重写此代码,以便我可以使用多个 class.

这是代码

<div id="trip_2022-12-31"></div>
<div id="trip_2021-11-01 01:02:12"></div>
 <div id="trip_2024-01-01"></div>
 <div id="trip_2023-02-01"></div>
 <div id="trip_2023-01-04"></div>
   
    <script>
        function TimeRemaining(){
   var els = document.querySelectorAll('[id^="trip_"]');
   for (var i=0; i<els.length; i++) {
     var el_id = els[i].getAttribute('id');
     var end_time = el_id.split('_')[1];
     var deadline = new Date(end_time);
     var now = new Date();
     var t = Math.floor(deadline.getTime() - now.getTime());
     var days = Math.floor(t / (1000 * 60 * 60 * 24));
     var hours = Math.floor((t % (1000 * 60 * 60 * 24))/(1000 * 60 * 60));
     var minutes = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60));
     var seconds = Math.floor((t % (1000 * 60)) / 1000);
     if (t < 0) {
        document.getElementById("trip_" + end_time).innerHTML = 'EXPIRED';
     }else{
        document.getElementById("trip_" + end_time).innerHTML = days + "d " + hours + "h " + minutes + "m " + seconds + "s";
     }
   }
}

function StartTimeRemaining(){
    TimeRemaining();
    setInterval(function(){
        TimeRemaining();
    }, 1000)
}


StartTimeRemaining();
    </script>
        <div class="trip_2022-12-31"></div>
        <div class="trip_2021-11-01 01:02:12">
    </div>
         <div class="trip_2024-01-01"></div>
         <div class="trip_2023-02-01"></div>
         <div class="trip_2023-01-04"></div>
        
    <script>
function TimeRemaining() {
  var els = [...document.querySelectorAll('[class^="trip_"]')];
  els.map(el => {
    var end_time = el.className.split("_")[1]
    var deadline = new Date(end_time);
    var now = new Date();
    var t = Math.floor(deadline.getTime() - now.getTime());
    var days = Math.floor(t / (1000 * 60 * 60 * 24));
    var hours = Math.floor((t % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    var minutes = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = Math.floor((t % (1000 * 60)) / 1000);
    if (t < 0) {
      document.getElementsByClassName("trip_" + end_time)[0].innerText = 'EXPIRED';
    } else {
      document.getElementsByClassName("trip_" + end_time)[0].innerText = days + "d " + hours + "h " + minutes + "m " + seconds + "s";
    }
  })
  window.requestAnimationFrame(TimeRemaining);
}

function StartTimeRemaining() {
  TimeRemaining();
  window.requestAnimationFrame(TimeRemaining);
}

StartTimeRemaining()


</script>

辛苦了兄弟

我稍微更改了您的代码。试试这个:

function TimeRemaining() {
  var els = [...document.querySelectorAll('[class^="trip_"]')];
  els.forEach(el => {
    var end_time = el.className.split("_")[1]
    var deadline = new Date(end_time);
    var now = new Date();
    var t = Math.floor(deadline.getTime() - now.getTime());
    var days = Math.floor(t / (1000 * 60 * 60 * 24));
    var hours = Math.floor((t % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    var minutes = Math.floor((t % (1000 * 60 * 60)) / (1000 * 60));
    var seconds = Math.floor((t % (1000 * 60)) / 1000);
    if (t < 0) {
      document.getElementsByClassName("trip_" + end_time)[0].innerText = 'EXPIRED';
    } else {
      document.getElementsByClassName("trip_" + end_time)[0].innerText = days + "d " + hours + "h " + minutes + "m " + seconds + "s";
    }
  })
  window.requestAnimationFrame(TimeRemaining);
}

function StartTimeRemaining() {
  TimeRemaining();
  window.requestAnimationFrame(TimeRemaining);
}

StartTimeRemaining()
<div class="trip_2022-12-31"></div>
<div class="trip_2021-11-01 01:02:12"></div>
<div class="trip_2024-01-01"></div>
<div class="trip_2023-02-01"></div>
<div class="trip_2023-01-04"></div><br>[Added to check expiration function]
<div class="trip_2021-2-17"></div>

具体来说,我缩短了 el_id,因为它没有太多用途,我把整个东西放在 forEach 中。我还将 getElementById 更改为 getElementsByClassName(...)[0]。我还将 innerHTML 更改为 innerText,因为 innerText 将文本按原样放入,并防止出现特殊字符问题。最后,我将 setTimeout 更改为 requestAnimationFrame,因为这通常会在不妨碍其他功能的情况下尽可能频繁地调用。这是为了显示尽可能接近真实时间的时间,因为如果页面在一秒的一半时间加载,那么计时器将关闭半秒。

当您调用 document.querySelectorAll('[id^="trip_"]'); 时,您有一个对单个 DIV 元素的引用,因此您无需进一步调用 getElementByIdgetElementsByClassName - 只需使用来自节点列表的引用。

我稍微修改了 HTML 结构,因为使用 className 来保存日期时间信息对我来说似乎是一个糟糕的选择。引入 dataset 属性是为了允许在这种情况下使用任意数据。这使得 class 可以自由地用于其他更合适的目的。

使用 dataset 意识形态可以很好地扩展它,也许可以包括计时器实际用途的详细信息。下面的代码使用 data-event 属性在计时器完成时显示该信息(或在 运行 时显示为标题)

document.addEventListener('DOMContentLoaded',()=>{
  /* Maintain a reference to each timer activated */
  let timers={};

  /* Time calculation constants */
  const yr=365.25;
  const min=1000 * 60;
  const hr=min * 60;
  const day=60 * 24;

  /* Find all the DIV elements that have `trip` data */
  document.querySelectorAll('div[data-trip]').forEach( ( div, i )=>{
    (function( trip ){

      timers[i]=NaN;

      (function(){
        /* calculate the delta between now and the date in question */
        let t=Math.floor( new Date( trip ).getTime() - new Date().getTime() );

        /* initialise the timer */
        timers[i]=setTimeout( arguments.callee, 1000 );

        /* perform the main time calculations */
        let obj={
          y:Math.floor( t / ( min * day * yr ) ),
          d:Math.floor( t / ( min * day ) ),
          h:Math.floor( ( t % ( min * day ) ) / hr ),
          m:Math.floor( ( t % hr ) / min ),
          s:Math.floor( ( t % min ) / 1000 )
        };


        /* Display the countdown */
        let output=['<span>'+obj.s+'</span>secs'];
        if( obj.m > 0 )output.unshift('<span>'+obj.m+'</span>mins');
        if( obj.h > 0 )output.unshift('<span>'+obj.h+'</span>hours');
        if( obj.y > 0 ){
          /* if the number of years is greater than zero - calculate remaining days */
          if( obj.d > 0 )output.unshift('<span>'+Math.ceil( obj.d - ( obj.y * yr ) )+'</span>days');
          output.unshift('<span>'+obj.y+'</span>yrs');
        }else{
          if( obj.d > 0 )output.unshift('<span>'+obj.d+'</span>days');
        }

        div.innerHTML=output.join(', ');
        div.title=div.dataset.event;


        /* display final message and cancel timer if expired */
        if( t <= 0 ){
          div.innerHTML=[ 'Expired', div.dataset.event ].join( ' - ' );
          div.className='expired';
          /* clear the timer */
          clearTimeout( timers[ i ] );
          delete timers[i];
        }
      })();
    })( div.dataset.trip );// assign the trip data/date as arg to the anonymous function
  });
});
.expired{color:red}
div[data-trip]{font-family:monospace;font-size:1.1rem;margin:0.5rem auto;cursor:pointer;}
div[data-trip] span{font-weight:bold;color:green}
<div data-trip='2021-03-22 12:30:00' data-event='Get Covid-19 vaccination'></div>
<div data-trip='2022-12-31' data-event='Go to Rouen'></div>
<div data-trip='2021-12-01 01:02:12' data-event='Skiing in Verbier'></div>
<div data-trip='2024-09-28' data-event='MX Des Nations'></div>
<div data-trip='2026-02-06' data-event='Winter Olympics 2026 in Cortina'></div>
<div data-trip='2023-01-04' data-event='World Spaghetti Day'></div>
<div data-trip='2021-03-22 08:30:00' data-event='Do important stuff'></div>