首页 > 解决方案 > 如何将字符串附加到 JavaScript 中数字的 innerText 以用于动画计数器

问题描述

在此处输入图像描述

我用基本的 HTML、CSS 和 JavaScript 构建了一个股票/计数器动画,它运行良好。这是为了让网站展示使用服务时性能和现金流如何得到改善,所以我目前让它工作并计数到我的目标数量,我想在这些目标的末尾附加一个字符串,而不是(例如),最终目标显示 35,我希望它显示 '35%' 或另一个元素,'2.5x'。

如果它是一个整数,我基本上想在末尾附加一个'%',如果它是一个小数,我想附加一个'x'。

我遇到的问题是,当我最后尝试将这些字符串中的一个附加到我的计数器上时,它会破坏一切并且只会返回 0.01% 而不是我的目标数字,即 35、70、20 等。

counter.innerText = Math.ceil(count + inc) + '%'例如,如果我尝试添加,它会破坏一切!我也尝试添加.toString()到末尾,然后附加 '%' 但还是一样。

这些是我的文件,我确定我在某个地方犯了一个愚蠢的错误,所以任何帮助将不胜感激!

HTML:

<div class="ticker-container">
  <h1 class='ticker-header'>The Superpowers of Inclusion & Diversity are clear</h1>
</div>

<section class='counters'>
  <div class='counter-container'>
    <div class='num-container'>
      <div class="counter" data-target='35'>0</div>
      <h4 class='count-subheader'>Better financial performance</h4>
      <p class='tick-p'>McKinsey</p>
    </div>
    <div class='num-container'>
      <div class="counter" data-target='70'>0</div>
      <h4 class='count-subheader'>More revenue from innovation</h4>
      <p class='tick-p'>BCG</p>
    </div>
    <div class='num-container'>
      <div class="counter" data-target='20'>0</div>
      <h4 class='count-subheader'>Higher revenue</h4>
      <p class='tick-p'>BCG</p>
    </div>
    <div class='num-container'>
      <div class="counter" data-target='2.5'>0</div>
      <h4 class='count-subheader'>Higher cashflow per employee</h4>
      <p class='tick-p'>HBR</p>
    </div>
  </div>
  </section>

CSS:

@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;700;');

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Roboto', sans-serif;
  background-image: linear-gradient(to right, #923CC7 , #B978E1);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.counter-container {
  max-width: 1200px;
  margin: 0 auto;
  overflow: auto;
}

.ticker-container {
  flex: 1;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ticker-header {
  font-size: 48px;
  margin-top: 20px;
}

.counters {
  padding: 50px 20px;
}

.counter-container {
  display: grid;
  grid-gap: 40px;
  grid-template-columns: repeat(4, 1fr);
  text-align: center;
}

.counter {
  font-size: 55px;
  margin: 10px 0;
  background-color: white;
  border-radius: 50%;
  width: 120px;
  height: 120px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.count-subheader {
  font-size: 17px;
  margin-top: 25px;
}

.tick-p {
  color: white;
  margin-top: 20px;
}


.num-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

@media(max-width: 700px) {
  .counter-container {
    grid-template-columns: repeat(2, 1fr);
  }
}

JavaScript:

const counters = document.querySelectorAll('.counter');
const speed = 200;
const decSpeed = 30;

counters.forEach(counter => {
  const updateCount = () => {
    const target = +counter.getAttribute('data-target');
    const count = +counter.innerText;
    
    const inc = target / speed;
    
    const decInc = target / decSpeed;
    
    if (count < target && target % 1 === 0) {
      counter.innerText = Math.ceil(count + inc)
      setTimeout(updateCount, 1);
      
    } else if (count < target && target % 1 !== 0) {
      counter.innerText = (count + decInc).toFixed(1)
      setTimeout(updateCount, 1);
    } else {
      count.innerText = target;
    }
  }
  
  
  updateCount();
})

标签: javascripthtmlcsscounter

解决方案


问题是这一行:

const count = +counter.innerText;

一旦您向 innerText 添加了一个符号,下次这将不会返回正确的数字 ( NaN)。

您可以通过在转换为数字之前删除符号部分来修复它:

const count = +counter.innerText.slice(0, -1);

const counters = document.querySelectorAll('.counter');
const speed = 200;
const decSpeed = 30;

counters.forEach(counter => {
  const updateCount = () => {
    const target = +counter.getAttribute('data-target');
    const count = +counter.innerText.slice(0, -1);

    const inc = target / speed;

    const decInc = target / decSpeed;

    if (count < target && target % 1 === 0) {
      counter.innerText = Math.ceil(count + inc) + '%'
      setTimeout(updateCount, 1);

    } else if (count < target && target % 1 !== 0) {
      counter.innerText = (count + decInc).toFixed(1) + 'x';
      setTimeout(updateCount, 1);
    } else {
      count.innerText = target;
    }
  }

  updateCount();
})
@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;700;');
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: 'Roboto', sans-serif;
  background-image: linear-gradient(to right, #923CC7, #B978E1);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.counter-container {
  max-width: 1200px;
  margin: 0 auto;
  overflow: auto;
}

.ticker-container {
  flex: 1;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ticker-header {
  font-size: 48px;
  margin-top: 20px;
}

.counters {
  padding: 50px 20px;
}

.counter-container {
  display: grid;
  grid-gap: 40px;
  grid-template-columns: repeat(4, 1fr);
  text-align: center;
}

.counter {
  font-size: 55px;
  margin: 10px 0;
  background-color: white;
  border-radius: 50%;
  width: 120px;
  height: 120px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.count-subheader {
  font-size: 17px;
  margin-top: 25px;
}

.tick-p {
  color: white;
  margin-top: 20px;
}

.num-container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

@media(max-width: 700px) {
  .counter-container {
    grid-template-columns: repeat(2, 1fr);
  }
}
<div class="ticker-container">
  <h1 class='ticker-header'>The Superpowers of Inclusion & Diversity are clear</h1>
</div>

<section class='counters'>
  <div class='counter-container'>
    <div class='num-container'>
      <div class="counter" data-target='35'>0</div>
      <h4 class='count-subheader'>Better financial performance</h4>
      <p class='tick-p'>McKinsey</p>
    </div>
    <div class='num-container'>
      <div class="counter" data-target='70'>0</div>
      <h4 class='count-subheader'>More revenue from innovation</h4>
      <p class='tick-p'>BCG</p>
    </div>
    <div class='num-container'>
      <div class="counter" data-target='20'>0</div>
      <h4 class='count-subheader'>Higher revenue</h4>
      <p class='tick-p'>BCG</p>
    </div>
    <div class='num-container'>
      <div class="counter" data-target='2.5'>0</div>
      <h4 class='count-subheader'>Higher cashflow per employee</h4>
      <p class='tick-p'>HBR</p>
    </div>
  </div>
</section>


推荐阅读