Studio Headphones
SKU: 700.954.29
100
299
When we first checked out our new headphones, we noticed the box said “improved bass”. We had to wonder if this was marketing jargon or the real thing? But it only took a moment to realize that bass was not kidding.
* */ (function () { 'use strict'; if (!window.NCDM_DELIVERY) { console.error('[delivery-datepicker] Сначала подключите delivery-date.js'); return; } var CORE = window.NCDM_DELIVERY; // ==================== НАСТРОЙКИ ==================== var CONFIG = { // Залейте оба файла в «Файловый менеджер» Тильды и подставьте ссылки // на static.tildacdn.com — надёжнее, чем внешний CDN. lib: { css: 'https://cdn.jsdelivr.net/npm/air-datepicker@3.5.3/air-datepicker.css', js: 'https://cdn.jsdelivr.net/npm/air-datepicker@3.5.3/air-datepicker.js' }, dateInput: 'input[type="date"], input[data-delivery-date]', form: '.t706__form, .t-form', maxDaysAhead: 60, // насколько далеко вперёд можно выбрать дату autoSelectFirst: false, // сразу подставлять ближайшую доступную дату mobileBreakpoint: 640, // ниже — календарь открывается модалкой placeholderEmpty: 'Сначала выберите город доставки', placeholderReady: 'Выберите дату доставки', theme: { accent: '#111111', // цвет выбранного дня radius: '8px', zIndex: 100000000 // выше попапа корзины Тильды } }; var LOCALE_RU = { days: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'], daysShort: ['Вос', 'Пон', 'Вто', 'Сре', 'Чет', 'Пят', 'Суб'], daysMin: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'], months: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'], monthsShort: ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'], today: 'Сегодня', clear: 'Очистить', dateFormat: 'dd.MM.yyyy', timeFormat: 'HH:mm', firstDay: 1 }; var DAY = 86400000; // ==================== ЗАГРУЗКА БИБЛИОТЕКИ ==================== var libPromise = null; function loadLib() { if (libPromise) return libPromise; libPromise = new Promise(function (resolve, reject) { if (window.AirDatepicker) return resolve(); var link = document.createElement('link'); link.rel = 'stylesheet'; link.href = CONFIG.lib.css; document.head.appendChild(link); var style = document.createElement('style'); style.textContent = '.air-datepicker{' + '--adp-z-index:' + CONFIG.theme.zIndex + ';' + '--adp-accent-color:' + CONFIG.theme.accent + ';' + '--adp-color-current-date:' + CONFIG.theme.accent + ';' + '--adp-border-radius:' + CONFIG.theme.radius + ';' + '--adp-font-family:inherit;font-family:inherit;}' + '.air-datepicker-cell.-disabled-{opacity:.28;text-decoration:line-through;cursor:not-allowed;}' + '.ncdm-dp-hint{font-size:12px;line-height:1.4;margin-top:6px;opacity:.65;}' + '.ncdm-dp-input{cursor:pointer;}' + '.ncdm-dp-input[disabled]{cursor:not-allowed;opacity:.6;}'; document.head.appendChild(style); var script = document.createElement('script'); script.src = CONFIG.lib.js; script.onload = resolve; script.onerror = function () { reject(new Error('air-datepicker не загрузился')); }; document.head.appendChild(script); }); return libPromise; } // ==================== ХЕЛПЕРЫ ==================== /** UTC-полночь -> локальный Date (air-datepicker работает с локальными датами). */ function tsToDate(ts) { var d = new Date(ts); return new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()); } /** Локальный Date -> UTC-полночь для функций ядра. */ function dateToTs(date) { return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()); } function formatRu(ts) { return new Intl.DateTimeFormat('ru-RU', { weekday: 'short', day: 'numeric', month: 'long', timeZone: 'UTC' }).format(new Date(ts)); } function pad(n) { return n < 10 ? '0' + n : '' + n; } function formatValue(ts) { var d = new Date(ts); return pad(d.getUTCDate()) + '.' + pad(d.getUTCMonth() + 1) + '.' + d.getUTCFullYear(); } function getRegion(input) { var form = input.closest(CONFIG.form) || document; return CORE.getSelectedRegion(form); } function getHint(input) { var hint = input.parentNode.querySelector('.ncdm-dp-hint'); if (!hint) { hint = document.createElement('div'); hint.className = 'ncdm-dp-hint'; input.parentNode.appendChild(hint); } return hint; } /** Значение должно попасть в заказ Тильды — дублируем нативные события. */ function commit(input, value) { input.value = value; input.dispatchEvent(new Event('input', { bubbles: true })); input.dispatchEvent(new Event('change', { bubbles: true })); } // ==================== ИНИЦИАЛИЗАЦИЯ ПОЛЯ ==================== function attach(input) { if (input._ncdmDp) return; // нативный date-пикер нам мешает: переводим поле в текст и запрещаем ручной ввод if (input.type === 'date') input.type = 'text'; input.readOnly = true; input.autocomplete = 'off'; input.classList.add('ncdm-dp-input'); var dp = new AirDatepicker(input, { locale: LOCALE_RU, autoClose: true, isMobile: window.innerWidth < CONFIG.mobileBreakpoint, position: 'bottom left', minDate: new Date(), maxDate: tsToDate(CORE.getMinDeliveryDate('msk') + CONFIG.maxDaysAhead * DAY), onRenderCell: function (params) { if (params.cellType !== 'day') return; var region = getRegion(input); if (!region) return { disabled: true }; if (!CORE.isDateAllowed(region, dateToTs(params.date))) return { disabled: true }; }, onSelect: function (params) { if (!params.date) return; commit(input, formatValue(dateToTs(params.date))); } }); input._ncdmDp = dp; sync(input); } /** Пересчёт границ под текущий регион и время. Вызывается при любой смене формы. */ function sync(input) { var dp = input._ncdmDp; if (!dp) return; var region = getRegion(input); var hint = getHint(input); if (!region) { dp.clear(); input.value = ''; input.disabled = true; input.placeholder = CONFIG.placeholderEmpty; hint.textContent = ''; return; } input.disabled = false; input.placeholder = CONFIG.placeholderReady; var min = CORE.getMinDeliveryDate(region); dp.update({ minDate: tsToDate(min), maxDate: tsToDate(min + CONFIG.maxDaysAhead * DAY) }); // выбранная ранее дата могла стать недоступной (сменили город / прошло 11:00) var selected = dp.selectedDates[0]; if (selected && !CORE.isDateAllowed(region, dateToTs(selected))) { dp.clear(); input.value = ''; } if (!dp.selectedDates.length && CONFIG.autoSelectFirst) { dp.selectDate(tsToDate(min)); } hint.textContent = 'Ближайшая доставка — ' + formatRu(min) + (region === 'mo' ? ' (по МО без воскресений)' : ''); } // ==================== НАБЛЮДЕНИЕ ЗА КОРЗИНОЙ ==================== var timer = null; function scan() { clearTimeout(timer); timer = setTimeout(function () { var inputs = document.querySelectorAll(CONFIG.dateInput); if (!inputs.length) return; loadLib().then(function () { Array.prototype.forEach.call(document.querySelectorAll(CONFIG.dateInput), function (input) { if (input._ncdmDp) sync(input); else attach(input); }); }).catch(function (e) { console.error('[delivery-datepicker]', e); }); }, 120); } // корзина Тильды перерисовывается динамически new MutationObserver(scan).observe(document.documentElement, { childList: true, subtree: true }); document.addEventListener('change', scan, true); document.addEventListener('click', scan, true); window.addEventListener('load', scan); setInterval(scan, 60000); // подхватить наступление 11:00 на открытой странице scan(); window.NCDM_DELIVERY_PICKER = { CONFIG: CONFIG, scan: scan, attach: attach, sync: sync }; })();
Made on
Tilda