JavaScript и jQuery / Время прочтения статьи на jQuery и чистом JavaScript

Заметка создана: 01 февраля 2025 г.

Время прочтения (или просто чтения) — это оценка, сколько времени потребуется среднему человеку, чтобы прочитать текст. Обычно оно рассчитывается на основе количества слов в статье, а также учитывает такие факторы, как:

  • Длина текста. Чем длиннее текст, тем больше времени потребуется на его прочтение.
  • Сложность текста. Сложные тексты с большим количеством технических терминов и сложных предложений требуют больше времени для понимания.
  • Размер шрифта. Крупный шрифт облегчает чтение, а мелкий, наоборот, усложняет его.
  • Наличие изображений. Изображения могут сделать текст более привлекательным, но они также могут замедлить чтение, если их слишком много.

Реализация на jQuery

Ниже представлен код на jQuery для реализации функции расчета времени чтения. В нем реализовано склонение «минут» в зависимости от цифр и гибкая настройка (вы самостоятельно можете сами примерную скорость чтения в минуту – так будет формироваться общее время чтения статьи), также есть возможность включить картинки в общее время прочтения.

За настройки отвечают параметры (находятся в последних строках):

images — время в секундах, которое уходит на просмотр одного изображения;

wpm — среднее количество слов, которое человек читает в минуту.

(function($) {
    $.fn.readtime = function(options) {
        // Значения по умолчанию
        var defaults = {
            format:  '#',
            wrapper: 'time',
            images: 7,     // Время на одно изображение (в секундах)
            wpm: 250       // Скорость чтения (слов в минуту)
        };

        // Объединяем переданные параметры с настройками по умолчанию
        options = $.extend(defaults, options);

        return this.each(function() {
            // Получаем текстовое содержимое элемента
            var text = this.textContent || this.innerText || '';

            // Подсчитываем количество слов в тексте
            var words = text.replace(/(^\s*)|(\s*$)/gi, '')
                            .replace(/[ ]{2,}/gi, ' ')
                            .replace(/\n /, '\n')
                            .split(' ').length;

            // Рассчитываем время на основе количества слов
            var time = (words / options.wpm) * 60;

            // Добавляем время на изображения
            if (options.images) {
                time += ($(this).find('img').length * options.images);
            }

            // Округляем до ближайшего целого числа и переводим в минуты
            time = Math.round(time / 60);

            // Форматируем выводимое значение
            time = options.format.replace(/#/, time);

            // Создаем элемент для отображения времени
            var element = document.createElement(options.wrapper);

            // Функция для склонения слова "минута"
            function declOfNum(number, titles) {
                cases = [2, 0, 1, 1, 1, 2];
                return titles[(number % 100 > 4 && number % 100 < 20) ? 2 : cases[(number % 10 < 5) ? number % 10 : 5]];
            }

            var title = declOfNum(time, ['минута', 'минуты', 'минут']);

            // Вставляем результат в элемент с классом .time_read
            $('.time_read').html(time + ' ' + title);
        });
    };
}(jQuery));

// Используем плагин с настройками
$(".text_read").readtime({
    images: 7,
    wpm: 250
});
  • Значения по умолчанию. Определяем значения по умолчанию для скорости чтения и времени на изображение.
  • Подсчет слов. Извлекаем текст из элемента и подсчитываем количество слов.
  • Добавление времени на изображения. Если в элементе есть изображения, добавляем к общему времени чтения дополнительные секунды.
  • Форматирование результата. Используем функцию declOfNum для правильного склонения слова «минута» в зависимости от значения.
  • Вывод результата. Вставляем результат в элемент с классом .time_read.

Если на странице текст будет меньше среднего количества слов указанных в параметре wpm, то скрипт будет выводить время прочтения 0. Чтобы исправить это найдите в скрипте строчку: title=declOfNum(time,['минута','минуты','минут']); и над ней вставьте: if(time == 0) { var time = 1; }.

Реализация на чистом JavaScript

Теперь посмотрим, как можно реализовать тот же функционал, но уже без jQuery.

(function() {
    function readtime(selector, options) {
        // Значения по умолчанию
        const defaults = {
            format: '#',
            wrapper: 'time',
            images: 7,    // Время на каждое изображение (в секундах)
            wpm: 250      // Скорость чтения (слов в минуту)
        };

        // Объединяем параметры с настройками по умолчанию
        options = Object.assign({}, defaults, options);

        // Функция для склонения слова "минута" в зависимости от числа
        function declOfNum(number, titles) {
            const cases = [2, 0, 1, 1, 1, 2];
            return titles[(number % 100 > 4 && number % 100 < 20) ? 2 : cases[(number % 10 < 5) ? number % 10 : 5]];
        }

        // Получаем все элементы, соответствующие переданному селектору
        const elements = document.querySelectorAll(selector);

        elements.forEach(element => {
            // Получаем текстовое содержимое элемента
            const text = element.textContent || element.innerText || '';

            // Считаем количество слов в тексте
            const words = text.trim().replace(/[ ]{2,}/g, ' ').split(' ').length;

            // Расчет времени на основе количества слов
            let time = (words / options.wpm) * 60;

            // Добавляем время на изображения, если есть
            if (options.images) {
                time += (element.querySelectorAll('img').length * options.images);
            }

            // Округляем и преобразуем в минуты
            time = Math.round(time / 60);

            // Форматируем выводимое значение
            const formattedTime = options.format.replace(/#/, time);

            // Создаем элемент для отображения времени
            const timeElement = document.createElement(options.wrapper);
            const title = declOfNum(time, ['минута', 'минуты', 'минут']);

            // Добавляем текст с временем и склонением
            timeElement.textContent = `${formattedTime} ${title}`;

            // Вставляем время чтения в элемент с классом .time_read
            const timeReadElement = document.querySelector('.time_read');
            if (timeReadElement) {
                timeReadElement.innerHTML = ''; // Очищаем перед вставкой
                timeReadElement.appendChild(timeElement);
            }
        });
    }

    // Используем функцию readtime с нужным селектором и параметрами
    readtime(".text_read", {
        images: 7,
        wpm: 250
    });
})();
  1. Настройки по умолчанию. Как и в jQuery-версии, заданы значения по умолчанию для скорости чтения и времени на изображение.
  2. Подсчет слов. Используется textContent или innerText, чтобы извлечь текст и посчитать количество слов.
  3. Добавление времени для изображений. Время увеличивается в зависимости от количества изображений в элементе.
  4. Форматирование результата. Результат округляется и форматируется с правильным склонением слова «минута».
  5. Отображение результата. Вставляем результат в элемент .time_read.