javascript - 滚动到视口时的动画计数器 - 带有千位分隔符
问题描述
这个问题的脚本对我来说非常有用,直到我有需要包含数千个分隔符的数字。现在我得到一个错误“NAN”。我需要分隔符在那里。不知道如何解决这个问题。我能想到的唯一(hacky)的事情是只计算分隔符之间的每个组,所以对于 1,160,868,它就像
<span class="count">1</span>,<span class="count">160</span>,<span class="count">868</span>
// Counter animation
// inViewport jQuery plugin
// http://stackoverflow.com/a/26831113/383904
$(function($, win) {
$.fn.inViewport = function(cb) {
return this.each(function(i,el){
function visPx(){
var H = $(this).height(),
r = el.getBoundingClientRect(), t=r.top, b=r.bottom;
return cb.call(el, Math.max(0, t>0? H-t : (b<H?b:H)));
} visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
jQuery(function($) { // DOM ready and $ in scope
$(".count").inViewport(function(px) { // Make use of the `px` argument!!!
// if element entered V.port ( px>0 ) and
// if prop initNumAnim flag is not yet set
// = Animate numbers
if(px>0 && !this.initNumAnim) {
this.initNumAnim = true; // Set flag to true to prevent re-running the same animation
$(this).prop('Counter',0).animate({
Counter: $(this).text()
}, {
duration: 4000,
step: function (now) {
$(this).text(Math.ceil(now));
}
});
}
});
});
// end Counter animation
从技术上讲,这会起作用。如果这是我需要这样做的方式,我会的。但是对于我的后端团队来说,当他们从数据库中提取这些数字时,能够使用逗号分隔符获取数字会容易得多。
解决方案
要获得数千- 逗号分隔的字符串,请使用Number.prototype。toLocaleString ( )
console.log( (12345678).toLocaleString('en-US') );
在视口中时动画
对于您的具体情况,我可能会建议使用IntersectionObserver API ,而不是使用我在这个答案中的旧inViewport代码片段。
如果您需要将组作为单独的 SPAN 元素- 拆分toLocaleString
at 逗号的结果,将每个值包装成 a <span>
,最后join(",")
将 Array 包装回字符串:
const animNum = (EL) => {
if (EL._isAnimated) return; // Animate only once!
EL._isAnimated = true;
$(EL).prop('Counter', 0).animate({
Counter: EL.dataset.num
}, {
duration: 3000,
step: function(now) {
const text = (Math.ceil(now)).toLocaleString('en-US');
const html = text.split(",").map(n => `<span class="count">${n}</span>`).join(",");
$(this).html(html);
}
});
};
const inViewport = (entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) animNum(entry.target);
});
};
$("[data-num]").each((i, EL) => {
const observer = new IntersectionObserver(inViewport);
observer.observe(EL);
});
.count {
font-size: 1.5em;
color: fuchsia;
}
<p style="height: 200vh;">Scroll down....... This one will animate only once</p>
<div data-num="12345678"></div>
<p style="height: 200vh;">Scroll down....... The next one will always animate</p>
<div data-num="7536712"></div>
<p style="height: 100vh;">That's it!</p>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
推荐阅读
- python - 文档中的这个校验和是错误的还是我没有看到什么?
- java - ResponseEntity - 如何处理不同于 200 ok 的状态码?
- css - 我如何设计风格
像我启用的滑块一样? - r - 尽管 GET 请求有效,但无法在公司代理后面运行 RSelenium?
- python - Python抓取超过1页并消除重复
- reactjs - React/Jest/Enzyme - 在 .toHaveBeenCalledWith(event) 检查中监视 changeHandler 失败
- django - drf-yasg:在 Swagger 文档中显示 ListAPIView 的自定义分页
- mediawiki - 从文本文件更新 wiki 消息
- powerbi - 基于事实表的切片器对性能不利?
- javascript - 对象作为 React 子级无效(在尝试获取资源时发现:TypeError: NetworkError。)