<!--КОД ДЛЯ РАЗМЕТКИ ТОВАРОВ С ПРЕДЗАКАЗОМ-->
<script>
document.addEventListener("DOMContentLoaded", function() {
(function () {
const charText = 'Доступно до';
const lastDayText = 'Исчезнет через ';
const cardText = 'Предзаказ';
const cartTotalTermText = 'В корзине есть товар по предзаказу: <br>ваш заказ будет отправлен через ';
let snippetSearchRepeat = 0;
let tistore = setInterval(function() {
const productListNum = document.querySelector('.t-store__product-snippet');
if(productListNum) {
if(productListNum.hasAttribute("data-product-url")){
clearInterval(tistore);
createDateMark(true);
};
};
snippetSearchRepeat++;
if(snippetSearchRepeat>50) clearInterval(tistore);
}, 100);
const gridCont = document.querySelectorAll(".js-store-grid-cont");
let renderedCount = 0;
const totalGrids = gridCont.length;
gridCont.forEach(function(el) {
el.addEventListener('tStoreRendered', function(e) {
renderedCount++;
if (renderedCount === totalGrids) {
createDateMark();
renderedCount = 0;
}
});
});
function waitForGridElements(selector, callback) {
const checkInterval = setInterval(() => {
const elements = document.querySelectorAll(selector);
if (elements.length > 0) {
clearInterval(checkInterval);
callback(elements);
}
}, 100);
setTimeout(() => clearInterval(checkInterval), 10000);
}
waitForGridElements(".t-store__relevants-grid-cont", function(gridRelevantCont) {
let renderedRelevantCount = 0;
const totalRelevantGrids = gridRelevantCont.length;
gridRelevantCont.forEach(function (el, index) {
el.addEventListener('tStoreRendered', function(e) {
renderedRelevantCount++;
if (renderedRelevantCount === totalRelevantGrids) {
createDateMark();
renderedRelevantCount = 0;
}
});
});
});
//Получаем текущую дату
const currentDate = new Date();
currentDate.setHours(0, 0, 0, 0);
// Функция для склонения дней
function getDaysDeclension(days) {
const lastDigit = days % 10;
const lastTwoDigits = days % 100;
if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
return `${days} дней`;
}
switch (lastDigit) {
case 1:
return `${days} день`;
case 2:
case 3:
case 4:
return `${days} дня`;
default:
return `${days} дней`;
}
}
// Функция для парсинга даты из формата DD.MM.YYYY
function parseDateFromString(dateString) {
const parts = dateString.split('.');
if (parts.length !== 3) return null;
const day = parseInt(parts[0], 10);
const month = parseInt(parts[1], 10) - 1;
const year = parseInt(parts[2], 10);
return new Date(year, month, day);
}
function createDateMark(snippet){
setTimeout(function(){
if (typeof tStoreXHR !== 'undefined' || snippet ) {
let store = {};
let productBlock = null;
if(snippet){
productBlock = document.querySelector('.t-store__product-snippet');
if (productBlock) {
const charcsElements = productBlock.querySelectorAll('.js-store-prod-charcs');
if (charcsElements && charcsElements.length > 0) {
for (let element of charcsElements) {
const textContent = element.textContent || '';
const normalizedText = textContent.toLowerCase().trim();
const searchText = charText.toLowerCase().trim();
if (normalizedText.includes(searchText)) {
if (textContent.includes(':')) {
const parts = textContent.split(':');
if (parts.length >= 2) {
const result = parts[1].trim();
store.single = result;
}
}
}
}
} else {
}
} else {
console.log('Блок с классом t-store__product-snippet не найден');
}
}else{
store = tStoreXHR;
};
Object.keys(store).forEach(key => {
try {
let storeBlock = {};
let products = [];
let productsObj = {};
if(snippet){
const characteristics = [
{ title: charText,
value: store[key]
}
];
productsObj.characteristics = characteristics;
products.push(productsObj);
}else{
storeBlock = JSON.parse(store[key]['response']);
products = storeBlock.products;
};
if (!products || !Array.isArray(products)) {
products = storeBlock.relevants;
}
if (!products || !Array.isArray(products)) {
console.warn('Не удалось получить продукты из storeBlock');
return;
}
products.forEach(product => {
if (!product.characteristics || !Array.isArray(product.characteristics)) {
return; // Пропускаем продукты без характеристик
}
let productDate = null;
let uid = null;
// Ищем нужную характеристику
for (const char of product.characteristics) {
if (!char.title || !char.value) continue;
const titleNormalized = char.title.trim().toLowerCase();
const charTextNormalized = charText.trim().toLowerCase();
if (titleNormalized === charTextNormalized) {
productDate = char.value;
if(snippet) {
uid = productBlock.getAttribute('data-product-gen-uid');
}else{
uid = product.uid;
};
break;
}
}
if (!productDate || !uid) {
return;
}
const targetDate = parseDateFromString(productDate);
if (!targetDate) {
console.warn(`Неверный формат даты: ${productDate}`);
return;
}
// Вычисляем разницу в днях
const timeDiff = targetDate.getTime() - currentDate.getTime();
const daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24));
if (daysDiff <= 0) {
return; // Пропускаем если дата уже прошла
}
// Формируем текст с правильным склонением
const daysText = getDaysDeclension(daysDiff);
const fullText = lastDayText + daysText;
//Находим блоки на странице
const productSelector = `.js-product[data-product-gen-uid="${uid}"]`;
const productElements = document.querySelectorAll(productSelector);
if (productElements.length === 0) {
console.warn(`Не найден элемент с data-product-gen-uid="${uid}"`);
return;
}
productElements.forEach(productElement => {
if (productElement.classList.contains('prepay-product')) {
return; // Пропускаем уже обработанные элементы
}
productElement.classList.add('prepay-product');
productElement.setAttribute('data-prepayment-term', fullText);
productElement.setAttribute('data-prepayment-date', productDate);
const prepaymentMark = document.createElement('div');
prepaymentMark.className = 'prepayment-mark t-text';
prepaymentMark.textContent = cardText;
const slider = productElement.querySelector('.t-store__prod-popup__slider');
if(slider){
slider.appendChild(prepaymentMark);
}else{
productElement.appendChild(prepaymentMark);
};
const productNameElement = productElement.querySelector('.js-product-name');
if (productNameElement) {
const prepaymentTerm = document.createElement('div');
prepaymentTerm.className = 'prepayment-term t-text';
prepaymentTerm.textContent = fullText;
productNameElement.parentNode.insertBefore(
prepaymentTerm,
productNameElement.nextSibling
);
}
});
});
} catch (error) {
console.error(`Ошибка при обработке ключа ${key}:`, error);
}
});
} else {
console.warn('Переменная tStoreXHR не определена');
}
}, 300);
};
// Обработчик кликов по товарам, открытие popup
document.addEventListener('click', function(event) {
if (event.target.closest('a[href*="/tproduct/"]')) {
const link = event.target.closest('a[href*="/tproduct/"]');
const productElement = link.closest('.js-product');
setTimeout(() => {
const popup = document.querySelector('.t-popup.t-popup_show .t-store__product-popup');
if (popup) {
const existingMark = popup.querySelector('.prepayment-mark');
const existingTerm = popup.querySelector('.prepayment-term');
if (existingMark) existingMark.remove();
if (existingTerm) existingTerm.remove();
popup.classList.remove('prepay-product');
popup.removeAttribute('data-prepayment-term');
popup.removeAttribute('data-prepayment-date');
// проверяем, есть ли у товара данные для предзаказа
if (productElement) {
const prepaymentTerm = productElement.getAttribute('data-prepayment-term');
const genUid = productElement.getAttribute('data-product-gen-uid');
const prepaymentDate = productElement.getAttribute('data-prepayment-date');
if (prepaymentTerm && genUid) {
const popupGenUid = popup.getAttribute('data-product-gen-uid');
if (popupGenUid === genUid) {
const prepaymentMark = document.createElement('div');
prepaymentMark.className = 'prepayment-mark t-text';
prepaymentMark.textContent = cardText;
if (popup.firstChild) {
popup.insertBefore(prepaymentMark, popup.firstChild);
} else {
popup.appendChild(prepaymentMark);
}
// Находим элемент с именем продукта в попапе
const productNameElement = popup.querySelector('.js-product-name');
if (productNameElement) {
const prepaymentTermElem = document.createElement('div');
prepaymentTermElem.className = 'prepayment-term t-text';
prepaymentTermElem.textContent = prepaymentTerm;
productNameElement.parentNode.insertBefore(
prepaymentTermElem,
productNameElement.nextSibling
);
}
popup.classList.add('prepay-product');
popup.setAttribute('data-prepayment-term', prepaymentTerm);
popup.setAttribute('data-prepayment-date', prepaymentDate);
} else {
console.log(`UID не совпадают: попап ${popupGenUid}, продукт ${genUid}`);
}
} else {
}
}
} else {
}
}, 300);
}
});
//Добавить товар в корзину, отслеживание
document.addEventListener('click', function(event) {
if (event.target.closest('a[href*="#order"]')) {
const link = event.target.closest('a[href*="#order"]');
const productElement = link.closest('.js-product');
if (productElement && productElement.classList.contains('prepay-product')) {
const genUid = productElement.getAttribute('data-product-gen-uid');
const prepaymentDate = productElement.getAttribute('data-prepayment-date');
setTimeout(function() {
const cart = window.tcart;
if (cart && cart.products) {
const products = cart.products;
const product = products.find(function(p) {
return p.gen_uid === genUid;
});
if (product) {
product.prepayment_date = prepaymentDate;
tcart__saveLocalObj();
}
}
}, 300);
}
}
});
//Отслеживание и разметка товара в корзине
t_onReady(function() {
setTimeout(function() {
t_onFuncLoad('tcart__init',function() {
markInCart();
});
},200);
});
function markInCart(){
const t706Element = document.querySelector('.t706');
if (!t706Element) {
return;
}
let cartTotals;
if (t706Element.hasAttribute('data-cart-fullscreen')) {
cartTotals = document.querySelector('.t706__cartpage-totals');
} else {
cartTotals = document.querySelector('.t706__cartwin-totalamount-wrap');
}
if (!cartTotals) {
return;
}
const observer = new MutationObserver(() => {
clearTimeout(window.prepaymentTimeout);
clearTimeout(window.prepaymentTimeoutDeleteTime);
window.prepaymentTimeout = setTimeout(updatePrepaymentInfo, 300);
window.prepaymentTimeoutDeleteTime = setTimeout(updatePrepaymentInfo, 4500);
});
observer.observe(cartTotals, {
childList: true,
subtree: true,
characterDataOldValue: true
});
function updatePrepaymentInfo() {
const cart = window.tcart;
if (!cart || !cart.products || !Array.isArray(cart.products)) {
return;
}
const prepaymentProductIndices = [];
const daysDiffValues = [];
cart.products.forEach((product, productIndex) => {
if (product.prepayment_date) {
const productDate = product.prepayment_date;
const targetDate = parseDateFromString(productDate);
if (!targetDate) {
console.warn(`Неверный формат даты: ${productDate}`);
return;
}
// Вычисляем разницу в днях
const timeDiff = targetDate.getTime() - currentDate.getTime();
const daysDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24));
if (daysDiff <= 0) {
// Если дата прошла, удаляем пометку
removePrepaymentMarking(productIndex);
return;
}
// Сохраняем индекс и разницу в днях
prepaymentProductIndices.push(productIndex);
daysDiffValues.push(daysDiff);
// Формируем текст с правильным склонением
const daysText = getDaysDeclension(daysDiff);
const fullText = lastDayText + daysText;
//Добавляем пометку для продукта с предоплатой
addPrepaymentMarking(productIndex, daysDiff, product.prepayment_term || fullText, fullText);
} else {
//Удаляем пометку для продукта без предоплаты
removePrepaymentMarking(productIndex);
}
});
//Обрабатываем итоговую информацию
if (prepaymentProductIndices.length > 0) {
let totalNumText;
if (prepaymentProductIndices.length === 1) {
// Если только один элемент с предоплатой
totalNumText = getDaysDeclension(daysDiffValues[0]);
} else {
// Если несколько элементов с предоплатой
const minDays = Math.min(...daysDiffValues);
const maxDays = Math.max(...daysDiffValues);
if (minDays === maxDays) {
totalNumText = getDaysDeclension(minDays);
} else {
// Определяем склонение для максимального числа
const maxDaysText = getDaysDeclension(maxDays);
// Убираем число из строки для получения правильного склонения
const declensionPart = maxDaysText.replace(maxDays, '').trim();
totalNumText = `${minDays}-${maxDays} ${declensionPart}`;
}
}
addTotalTermBlock(cartTotalTermText, totalNumText);
} else {
// Если нет продуктов с предоплатой, удаляем блок
removeTotalTermBlock();
}
}
// Функция для добавления пометки предоплаты к продукту
function addPrepaymentMarking(productIndex, daysDiff, cardTxt, fullText) {
const productElements = document.querySelectorAll(`.t706__product[data-cart-product-i="${productIndex}"]`);
productElements.forEach(productElement => {
productElement.classList.add('prepayment-product-in-cart');
productElement.setAttribute('data-term-num', daysDiff);
// Удаляем старые элементы, если есть
const oldMark = productElement.querySelector('.prepayment-mark');
const oldTerm = productElement.querySelector('.prepayment-term');
if (oldMark) oldMark.remove();
if (oldTerm) oldTerm.remove();
// Создаем и добавляем новый элемент для текста карточки
const prepaymentMark = document.createElement('div');
prepaymentMark.className = 'prepayment-mark t-text';
prepaymentMark.textContent = cardText;
productElement.appendChild(prepaymentMark);
// Создаем и добавляем новый элемент для срока
const prepaymentTerm = document.createElement('div');
prepaymentTerm.className = 'prepayment-term t-text';
prepaymentTerm.textContent = fullText;
productElement.appendChild(prepaymentTerm);
});
}
// Функция для удаления пометки предоплаты с продукта
function removePrepaymentMarking(productIndex) {
const productElements = document.querySelectorAll(`.t706__product[data-cart-product-i="${productIndex}"]`);
productElements.forEach(productElement => {
productElement.classList.remove('prepayment-product-in-cart');
productElement.removeAttribute('data-term-num');
const prepaymentMark = productElement.querySelector('.prepayment-mark');
const prepaymentTerm = productElement.querySelector('.prepayment-term');
if (prepaymentMark) prepaymentMark.remove();
if (prepaymentTerm) prepaymentTerm.remove();
});
}
// Функция для добавления блока с общей информацией о сроке
function addTotalTermBlock(cartTotalTermText, totalNumText) {
removeTotalTermBlock();
const blockHTML = `
<div class="total-term-text t-text">
<span>${cartTotalTermText}</span>
<span class="term-total-num">${totalNumText}</span>
</div>
`;
const containers = [
'.t706__sidebar-top',
'.t706__cartpage-info-wrapper',
'.t706__cartwin-top'
];
containers.forEach(selector => {
const container = document.querySelector(selector);
if (container) {
container.insertAdjacentHTML('afterbegin', blockHTML);
}
});
}
// Функция для удаления блока с общей информацией
function removeTotalTermBlock() {
const blocks = document.querySelectorAll('.total-term-text');
blocks.forEach(block => block.remove());
}
updatePrepaymentInfo();
};
})();
});
</script>
<style>
.prepayment-mark {
position: absolute;
top: 0;
left: 0;
z-index: 99;
background-color: #4a583f;
color: #fff;
border-radius: 10px;
padding: 2px 8px;
font-size: 14px;
}
.js-product {
position: relative;
}
.t-store__prod-popup__slider {
position: relative;
}
.prepayment-term {
background-color: #e6a551;
border-radius: 15px;
font-size: 12px;
font-weight: 600;
padding: 6px 10px;
width: max-content;
display: flex;
align-items: center;
gap: 5px;
margin-top: 5px;
}
.prepayment-term:before {
content: "";
background-image: url(https://static.tildacdn.com/tild3736-6338-4534-a633-616464336636/Group_7.svg);
background-size: cover;
width: 15px;
height: 15px;
display: inline-block;
}
.prepay-product .js-store-prod-all-charcs p:nth-last-child(3) {
display: none;
}
.t706__product {
position: relative;
}
.t706 .prepayment-mark {
position: absolute;
top: 0;
left: 0;
font-weight: 400;
font-size: 11px;
padding: 3px 6px;
border-radius: 15px 0 15px 0;
}
.t706 .prepayment-term {
position: absolute;
top: 0;
right: 0;
margin: 0;
font-weight: 400;
font-size: 11px;
padding: 3px 6px;
border-radius: 0 15px 0 15px;
}
.t706__product.prepayment-product-in-cart {
box-shadow: 0 0 0 1px #e2e2e2;
border-radius: 15px;
}
.t706__product {
padding: 20px 10px 0 10px;
box-sizing: border-box;
margin-bottom: 10px;
}
.total-term-text {
background-color: #fceeec;
border-radius: 15px;
padding: 10px;
font-size: 14px;
padding-left: 50px;
position: relative;
order: 1;
}
span.term-total-num {
font-weight: 600;
}
.total-term-text:before {
content: "";
background-image: url(https://static.tildacdn.com/tild3232-3934-4432-b763-393864626333/calendar-with-a-cloc.svg);
width: 22px;
height: 22px;
background-size: contain;
background-repeat: no-repeat;
display: inline-block;
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
}
.t706__sidebar-top {
display: grid;
row-gap: 10px;
padding-bottom: 10px;
}
.t706__cartpage-info-wrapper .total-term-text {
margin-bottom: 20px;
}
@media screen and (max-width:460px){
.prepayment-term {
padding: 6px 10px;
width: 100%;
box-sizing: border-box;
}
.prepayment-term:before {
width: 15px;
min-width: 15px;
height: 15px;
}
}
</style>