Добрый день! Я создал функцию, которая имитирует подсчет чисел. В итоге получил число без запятых.
Мой результат:
Что я хочу получить:
Мне нужно добавить запятую для тысячных, как в примере выше.
Код
let elements = document.querySelectorAll('#count-up-number');
let time = 5;
elements.forEach((element) => {
element.textContent = '0';
const updateCount = () => {
const number = parseInt(element.getAttribute('data-value'));
const value = +element.textContent;
const increment = number / 200;
if (value < number) {
element.textContent = `${Math.ceil(value + increment)}`;
setTimeout(updateCount, time);
}
}
updateCount();
})
<span class = "card-number" id = "count-up-number" data-value = "2495">2,495</span>
Селектор запроса с селектором идентификатора на самом деле не имеет смысла, потому что значения идентификатора элемента должны быть уникальными в документе. Вы получите список из нуля или одного элемента.
Вы можете добиться этого, преобразовав число в строку локали.
const number = 2496;
const formattedNumber = number.toLocaleString("en-US");
console.info(formattedNumber); // 2,496
Использование Intl.NumberFormat справится с этим, а также со странами, которые используют . в качестве разделителя тысяч и другими региональными вариантами.
new Intl.NumberFormat().format(number);
Значение по умолчанию без указания конкретных параметров будет делать именно то, что вы хотите.
Не предлагайте Intl.NumberFormat, он работает некорректно
Можно поподробнее, что работает не так?
Есть номер 3675. Это ожидаемый результат. Если я использую Intl.NumberFormat, я получаю 1008 вместо 3675.
Это второстепенная проблема. Теперь вы считываете текущее значение в виде строки '1,008', а +value вернет NaN и вызовет ошибку в вашем коде. Я бы рекомендовал сохранять значение счетчика в атрибуте данных, например, конечное значение, во время каждой итерации, без международного форматирования.
Вот почему я не использую Intl.NumberFormat.
Использование Intl.NumberFormat справится с этим, а также со странами, которые используют . в качестве разделителя тысяч и другими региональными вариантами.
new Intl.NumberFormat().format(number);
Значение по умолчанию без указания конкретных параметров будет делать именно то, что вы хотите для форматирования.
Однако это нарушит существующую реализацию, в которой вы используете +element.textContent для считывания отображаемого в данный момент значения. Как только вы достигнете значения> 1000, он больше не сможет анализировать значение из-за запятой. Вы можете обойти это, сохранив неформатированное значение в атрибуте элемента.
Обратите внимание, что html также был изменен, чтобы установить нулевое значение по умолчанию для data-count. Вы также можете поместить условие === undefined в функцию updateCount(), чтобы сделать то же самое во время холодного запуска.
let elements = document.querySelectorAll('#count-up-number');
let time = 5;
elements.forEach((element) => {
element.textContent = '0';
const updateCount = () => {
const number = parseInt(element.getAttribute('data-value'));
const value = parseInt(element.getAttribute('data-count'));
const increment = number / 200;
if (value < number) {
const newValue = Math.ceil(value + increment);
element.setAttribute('data-count', newValue);
element.textContent = new Intl.NumberFormat().format(newValue);
setTimeout(updateCount, time);
}
}
updateCount();
})
<span class = "card-number" id = "count-up-number" data-value = "2495" data-count = "0">2,495</span>
Intl.NumberFormat и toLocaleString являются возможными решениями, как указывалось в других ответах. Поэтому мой ответ сосредоточен на том, как мы могли бы реализовать это более «сделай сам»:
var str = '9012345678';
while (str.length % 3) str = '0' + str;
console.info(str.match(/.{1,3}/g).map((x, i) => i ? x : parseInt(x)).join(","));
Объяснение:
.map
наши куски в себя, за исключением первого, который мы отображаем на его целочисленный корреспондент, чтобы избавиться от предыдущих 0roes.join(",")
наши куски, чтобы получить формат, который мы хотели иметь
Оформить заказ Intl.NumberFormat