Javascript 有关如何在通过值数组进行映射时生成JS倒计时的指南

Javascript 有关如何在通过值数组进行映射时生成JS倒计时的指南,javascript,html,dom,mapping,Javascript,Html,Dom,Mapping,在将值数组映射到HTML时,我正在努力寻找显示每个项的倒计时计时器的最佳方法 我正在从事一个项目,在这个项目中,我从API访问值,并在我的网站上以卡片格式显示它们。所有信息都按预期显示,但我不知道如何为每张卡显示唯一的倒计时计时器 目前,我正在尝试在每次映射迭代中运行一个函数,该函数将生成倒计时并显示在“countdownId”的id上。这不起作用,因为我得到了错误'uncaughttypeerror:无法将属性'innerHTML'设置为null'。我知道这是因为在函数运行时没有生成id,但我

在将值数组映射到HTML时,我正在努力寻找显示每个项的倒计时计时器的最佳方法

我正在从事一个项目,在这个项目中,我从API访问值,并在我的网站上以卡片格式显示它们。所有信息都按预期显示,但我不知道如何为每张卡显示唯一的倒计时计时器

目前,我正在尝试在每次映射迭代中运行一个函数,该函数将生成倒计时并显示在“countdownId”的id上。这不起作用,因为我得到了错误'uncaughttypeerror:无法将属性'innerHTML'设置为null'。我知道这是因为在函数运行时没有生成id,但我无法找到显示实际倒计时的替代方法。我试着去研究,结果什么也没发生

提前感谢您的帮助

Index.html-将此限制为与显示所有卡相关的相关ID

<ul id="appTest"></ul>

    card.js-这是解析API和形成单个卡的地方

    import { initializeClock } from './timer';
    
    const rocketCard = (array) => {
    
        const cardReturn = array.map(indiv => {
        
      
            let rocketCard= `<li class='rocket-card'>
                            <img src="${indiv.rocketPhoto}" />
                            <h2>${indiv.rocketName}</h2>
                            <div class='card-body'>
                                <p class='card-subtitle'> Launch Date:</p>
                                <p>${indiv.launchDate}</p>
                                </br>
                                <p class='card-subtitle'>Launch Location: </p>
                                <p> ${indiv.location} </p>
                                <div id='countdownId'></div>
                                </br>
                                <p class='card-subtitle'>Upcoming Mission Description:</p>
                                <p class='card-desc'>${indiv.description}</p>
                                </div>
                                </li>`
            initializeClock('countdownId', indiv.launchDate)
            return rocketCard;
        })
        document
            .getElementById('appTest')
            .innerHTML = cardReturn.join('')
    }
    
    const rocketCollection = () => {
      
        let rocketArr = [];
     
        // fetch('https://ll.thespacedevs.com/2.0.0/launch/upcoming/?limit=12') //Live Data subject to limits
        fetch('https://lldev.thespacedevs.com/2.0.0/launch/upcoming/?limit=12') //Fetch stale data for development
        .then(response => response.json())
        .then(response => response.results.forEach(indiv => (
            rocketArr.push({
            rocketName: indiv.name,
            launchDate: indiv.window_start,
            rocketPhoto: indiv.image, 
            location: indiv.pad.location.name,
            description: indiv.mission ? indiv.mission.description : 'No description available'
        }))))
      .then(() => rocketCard(rocketArr))
    };
    
    
    从“/timer”导入{initializelock};
    常量rocketCard=(数组)=>{
    const cardReturn=array.map(indiv=>{
    让rocketCard=`li class='rocket-card'>
    ${indiv.rocketName}
    

    发布日期:

    ${indiv.launchDate}


    发布地点:

    ${indiv.location}


    即将到来的任务描述:

    ${indiv.description}

    ` 初始化锁('countdownId',独立启动日期) 返回火箭卡; }) 文件 .getElementById('appTest') .innerHTML=cardReturn.join(“”) } 常量火箭集合=()=>{ 让火箭手=[]; //取('https://ll.thespacedevs.com/2.0.0/launch/upcoming/?limit=12“)//受限制的实时数据 取('https://lldev.thespacedevs.com/2.0.0/launch/upcoming/?limit=12')//获取陈旧数据以进行开发 .then(response=>response.json()) .then(response=>response.results.forEach(indiv=>( 火箭推进器({ rocketName:indiv.name, 启动日期:独立窗口启动, 火箭照片:独立影像, 位置:indiv.pad.location.name, 描述:indiv.mission?indiv.mission.description:'没有可用的描述' })))) .然后(()=>rocketCard(rocketArr)) };
    timer.js-我用来创建倒计时计时器的当前函数

    const myTimer = (deadline) => {
        let theDeadline = new Date(deadline).getTime();
        let now = new Date().getTime();
        let timeleft = theDeadline - now;
        let days = Math.floor(timeleft / (1000 * 60 * 60 * 24));
        let hours = Math.floor((timeleft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        let minutes = Math.floor((timeleft % (1000 * 60 * 60)) / (1000 * 60));
        let seconds = Math.floor((timeleft % (1000 * 60)) / 1000);
       
        return {days, hours, minutes, seconds};
    };
    
    export const initializeClock = (id, endtime) => {
        const clock = document.getElementById(id);
        const timeinterval = setInterval(() => {
            const t = myTimer(endtime);
            clock.innerHTML =   'days: ' + t.days + '<br>' +
                                'hours: '+ t.hours + '<br>' +
                                'minutes: ' + t.minutes + '<br>' +
                                'seconds: ' + t.seconds;
            if (t.total <= 0) {
                clearInterval(timeinterval);
            }
        },1000);
    }
    
    constmytimer=(截止日期)=>{
    让deadline=新日期(截止日期).getTime();
    现在让我们=new Date().getTime();
    让timeleft=现在的底线;
    让天数=数学下限(时间下限/(1000*60*60*24));
    让小时数=数学楼层((时间限制%(1000*60*60*24))/(1000*60*60));
    让分钟数=数学楼层((时间限制%(1000*60*60))/(1000*60));
    让秒=数学地板((时间限制%(1000*60))/1000);
    返回{天,小时,分钟,秒};
    };
    导出常量InitializeLock=(id,endtime)=>{
    常量时钟=document.getElementById(id);
    常量时间间隔=设置间隔(()=>{
    常数t=我的计时器(结束时间);
    clock.innerHTML='days:'+t.days+'
    '+ '小时数:'+t.hours+'
    '+ '分钟数:'+t.minutes+'
    '+ “秒:”+t秒;
    如果(t.total让我们把它分成两部分

    首先是在DOM中打印内容。您正确地识别出
    无法将属性'innerHTML'设置为null'
    错误是因为元素尚未插入DOM。除此之外,我还看到了两个问题:

  • 在名为
    rocketCard
    的函数中,有一个名为
    rocketCard
    的变量。你在那里自找麻烦,因为每当你试图访问保存标记的变量时,你很可能会在意外情况下调用该函数。为了使调试更容易,我将该函数重命名为更符合它的实际功能:
    initDom
  • 每次倒计时都使用相同的ID—
    countdownId
    。因此,即使将标记正确插入到DOM中,也无法正常工作。我们需要为每次倒计时生成唯一的ID
  • 下面我将
    映射更改为
    forEach
    ,它首先将元素插入DOM(使用
    innerHTML+=
    ,而不是在最后一次将整个内容转储),然后初始化倒计时

    constmytimer=(截止日期)=>{
    让deadline=新日期(截止日期).getTime();
    现在让我们=new Date().getTime();
    让timeleft=现在的底线;
    让天数=数学下限(时间下限/(1000*60*60*24));
    让小时数=数学楼层((时间限制%(1000*60*60*24))/(1000*60*60));
    让分钟数=数学楼层((时间限制%(1000*60*60))/(1000*60));
    让秒=数学地板((时间限制%(1000*60))/1000);
    返回{
    天,
    小时,
    会议记录,
    秒
    };
    };
    const initializelock=(id,endtime)=>{
    常量时钟=document.getElementById(id);
    常量时间间隔=设置间隔(()=>{
    常数t=我的计时器(结束时间);
    clock.innerHTML='days:'+t.days+'
    '+ '小时数:'+t.hours+'
    '+ '分钟数:'+t.minutes+'
    '+ “秒:”+t秒; 如果(t.total{ 欺骗