计数中的大量数字在 safari 浏览器中显示 NaN

Large numbers in count-up show NaN in safari browser

我在 Vanilla JS 中创建了一个计数函数。一切正常。当您向下滚动到它时,计数器开始。不幸的是,大数字 35 000 000 在 iOS Safari 浏览器中显示为 NaN。我不知道为什么。请帮忙。看起来大数字在 iOS Safari 浏览器中不起作用。

var animationDuration = 3000;
var frameDuration = 1000 / 60;
var totalFrames = Math.round(animationDuration / frameDuration);
var easeOutQuad = t => t * (2 - t);
var animateCountUp = el => {
  let frame = 0;
  var countTo = parseInt(el.innerHTML.replace(/ /g, ''), 10);
  var counter = setInterval(() => {
    frame++;
    var progress = easeOutQuad(frame / totalFrames);
    var currentCount = Math.round(countTo * progress);
    if (parseInt(el.innerHTML, 10) !== currentCount) {
      el.textContent = currentCount.toLocaleString().replace(/,/g, ' ');
    }
    if (frame === totalFrames) {
      clearInterval(counter);
    }
  }, frameDuration);
};
var count = document.querySelectorAll('.countup'),
  once = 1;
document.addEventListener('scroll', function() {
  if (once == 1 && count[0].getBoundingClientRect().top < window.innerHeight) {
    once = 0;
    count.forEach(animateCountUp);
  }
});
<div style="position: fixed">
    <span class="countup">12 500</span>
    <span class="countup">35 000 000</span>
</div>
<div style="height: 5000px"></div>

为此使用 innerHTML 稍微不太理想,事实上 iOS Safari 正在为您的大数字添加标记,这会影响您的代码。它将它标识为电话号码并将该元素的内部 HTML 更改为:<a href="tel:35 000 000">35 000 000</a>。这是非常令人惊讶的,但你可以在这里看到它:

console.log(document.querySelector(".countup").innerHTML);
<span class="countup">35 000 000</span>

注意: 据我所知,仅在 iOS Safari 上。

改用 textContent 可行,因为文本未更改:

var animationDuration = 3000;
var frameDuration = 1000 / 60;
var totalFrames = Math.round(animationDuration / frameDuration);
var easeOutQuad = t => t * (2 - t);
var animateCountUp = el => {
  let frame = 0;
  var countTo = parseInt(el.textContent.replace(/ /g, ''), 10);
  var counter = setInterval(() => {
    frame++;
    var progress = easeOutQuad(frame / totalFrames);
    var currentCount = Math.round(countTo * progress);
    if (parseInt(el.textContent, 10) !== currentCount) {
      el.textContent = currentCount.toLocaleString().replace(/,/g, ' ');
    }
    if (frame === totalFrames) {
      clearInterval(counter);
    }
  }, frameDuration);
};
var count = document.querySelectorAll('.countup'),
  once = 1;
document.addEventListener('scroll', function() {
  if (once == 1 && count[0].getBoundingClientRect().top < window.innerHeight) {
    once = 0;
    count.forEach(animateCountUp);
  }
});
<div style="position: fixed">
    <span class="countup">12 500</span>
    <span class="countup">35 000 000</span>
</div>
<div style="height: 5000px"></div>

您还可以告诉 iOS Safari 不要通过添加 meta 标记作为 described in this question's answers:

<meta name="format-detection" content="telephone=no">

但据我所知,它会在整个页面范围内禁用它。

为什么不使用 counto 而是使用 DOM 作为要数的存储?

正如 TJ 所说,问题是 Safari 在使用 innerHTML 而不是 textContent 时对您的号码的处理

if (currentCount<=countTo) {
  el.textContent = currentCount.toLocaleString().replace(/,/g, ' ');
}

测试于 iOS 14.4

https://plungjan.name/SO/tl.html

var animationDuration = 3000;
var frameDuration = 1000 / 60;
var totalFrames = Math.round(animationDuration / frameDuration);
var easeOutQuad = t => t * (2 - t);
var animateCountUp = el => {
  let frame = 0;
  var countTo = parseInt(el.textContent.replace(/ /g, ''), 10); // do not use innerHTML here
  var counter = setInterval(() => {
    frame++;
    var progress = easeOutQuad(frame / totalFrames);
    var currentCount = Math.round(countTo * progress);
    if (currentCount<=countTo) {
      el.textContent = currentCount.toLocaleString().replace(/,/g, ' ');
    }
    if (frame === totalFrames) {
      clearInterval(counter);
    }
  }, frameDuration);
};
var count = document.querySelectorAll('.countup'),
  once = 1;
document.addEventListener('scroll', function() {
  if (once == 1 && count[0].getBoundingClientRect().top < window.innerHeight) {
    once = 0;
    count.forEach(animateCountUp);
  }
});
<div style="position: fixed">
    <span class="countup">12 500</span>
    <span class="countup">35 000 000</span>
</div>
<div style="height: 5000px"></div>