Подходит для настраиваемых CMS-потоков Tilda, в которых подробная страница поста сделана в Zero Block.
Что делает код
- Берёт дату из отдельного поля CMS, а не дату публикации.
- Добавляет перед ней иконку календаря.
- Считает слова только в тексте статьи: без заголовка, даты и фотографий.
- Делит количество слов на 140 слов в минуту, округляет результат и выводит `1 минута`, `2 минуты` или `5 минут` с иконкой часов.
- Срабатывает только на страницах, где есть нужные CMS-поля, поэтому не влияет на обычные страницы сайта.
- На телефоне строка остаётся компактной и помещается в шаблоне шириной от 320 px.
Что должно быть в потоке
В настройках полей у даты события задай имя переменной `event_date`. Для текстового поля статьи используй `article`.
В шаблоне подробной страницы оба поля должны быть выведены в Zero Block и связаны с полями потока: дата — с `event_date`, текст статьи — с `article`.
В шаблоне подробной страницы оба поля должны быть выведены в Zero Block и связаны с полями потока: дата — с `event_date`, текст статьи — с `article`.
Куда вставлять
Добавь на страницу-шаблон подробного поста HTML-блок T123 и помести его внизу страницы. Сохрани и опубликуй страницу-шаблон. Код не нужно вставлять в каждую карточку поста отдельно.
<style>
.nlm-event-meta-date .tn-atom {
display: inline-flex !important;
align-items: center;
white-space: nowrap;
}
.nlm-event-meta-date .tn-atom::before,
.nlm-event-meta-time::before {
content: "";
flex: 0 0 16px;
width: 16px;
height: 16px;
margin-right: 7px;
background-color: currentColor;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
}
.nlm-event-meta-date .tn-atom::before {
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4.5' width='18' height='16.5' rx='2'/%3E%3Cpath d='M8 2.5v4M16 2.5v4M3 10h18'/%3E%3C/svg%3E");
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4.5' width='18' height='16.5' rx='2'/%3E%3Cpath d='M8 2.5v4M16 2.5v4M3 10h18'/%3E%3C/svg%3E");
}
.nlm-event-meta-time {
display: inline-flex;
align-items: center;
margin-left: 18px;
}
.nlm-event-meta-time::before {
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v5l3.5 2'/%3E%3C/svg%3E");
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v5l3.5 2'/%3E%3C/svg%3E");
}
@media screen and (max-width: 359px) {
.nlm-event-meta-date .tn-atom {
font-size: 13px;
}
.nlm-event-meta-time {
margin-left: 14px;
}
}
</style>
<script>
(function () {
var WORDS_PER_MINUTE = 140;
function minuteWord(number) {
var lastTwo = number % 100;
var last = number % 10;
if (lastTwo >= 11 && lastTwo <= 14) return "минут";
if (last === 1) return "минута";
if (last >= 2 && last <= 4) return "минуты";
return "минут";
}
function addEventMeta() {
var dateField = document.querySelector('[data-fe-post-field="event_date"]');
var articleField = document.querySelector('[data-fe-post-field="article"]');
if (!dateField || !articleField) return false;
var dateAtom = dateField.querySelector(".tn-atom");
if (!dateAtom || dateAtom.querySelector(".nlm-event-meta-time")) return true;
var textBlocks = articleField.querySelectorAll(".t-redactor__text");
var articleText = textBlocks.length
? Array.prototype.map.call(textBlocks, function (block) {
return block.innerText;
}).join(" ")
: articleField.innerText;
var words = articleText.match(/[\p{L}\p{N}]+(?:[-'’][\p{L}\p{N}]+)*/gu) || [];
if (!words.length) return false;
var minutes = Math.max(1, Math.round(words.length / WORDS_PER_MINUTE));
var time = document.createElement("span");
dateField.classList.add("nlm-event-meta-date");
time.className = "nlm-event-meta-time";
time.textContent = minutes + " " + minuteWord(minutes);
time.setAttribute("aria-label", "Время чтения: " + time.textContent);
dateAtom.appendChild(time);
return true;
}
function init() {
if (addEventMeta()) return;
var observer = new MutationObserver(function () {
if (addEventMeta()) observer.disconnect();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
setTimeout(function () {
observer.disconnect();
}, 15000);
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();
</script>Если в другом потоке другие имена полей
Код не привязан к названию самого потока, но ему важны имена переменных. Если в другом CMS-потоке дата называется, например, `date_event`, а текст — `text`, замени в двух строках `event_date` и `article` на свои значения.
Скорость чтения меняется в строке `var WORDS_PER_MINUTE = 140;`. Для спокойного чтения оставь 140, для более быстрого можно поставить 160–180.
Скорость чтения меняется в строке `var WORDS_PER_MINUTE = 140;`. Для спокойного чтения оставь 140, для более быстрого можно поставить 160–180.
