Отлично! Добавим управление показом по времени и список URL-исключений.
Что будет сделано:
-
Показ 1 раз в 12 часов:
<li>
Используем localStorage для хранения времени последнего успешного показа видео.
-
Перед показом будем проверять, прошло ли 12 часов с последнего раза.
-
URL-исключения:
<li>
Создадим массив строк (URL-паттернов).
-
Перед показом будем проверять текущий URL страницы на соответствие этим паттернам.
-
Паттерн /bitrix/* будет означать "все URL, начинающиеся с /bitrix/".
Вот полный обновленный код:
`<!DOCTYPE html>
<title>Видео в углу (с контролем показа и исключениями)</title>
body {
min-height: 200vh; /* Просто для демонстрации прокрутки и позиционирования */
margin: 0;
font-family: sans-serif;
background-color: #f0f0f0;
padding-bottom: 400px; /* Добавляем отступ снизу */
}
.video-popup-container {
position: fixed;
bottom: 30px;
left: 30px;
width: 210px;
height: 360px; /* Общая высота блока */
background-color: #222; /* Фон на случай, если видео не полностью загрузится */
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
z-index: 9999;
overflow: hidden; /* Чтобы скруглённые углы работали для видео */
display: none; /* Изначально скрыт */
}
.video-popup-container.visible { /* Если будете использовать анимацию появления */
display: block;
}
.video-popup-container video {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.video-popup-close-btn {
position: absolute;
top: 5px;
right: 5px;
width: 25px;
height: 25px;
background-color: rgba(0, 0, 0, 0.5);
color: white;
border: none;
border-radius: 50%;
font-size: 16px;
line-height: 25px;
text-align: center;
cursor: pointer;
z-index: 10;
transition: background-color 0.2s;
}
.video-popup-close-btn:hover {
background-color: rgba(0, 0, 0, 0.8);
}
.video-popup-mute-btn {
position: absolute;
bottom: 10px;
left: 10px;
width: 30px;
height: 30px;
background-color: rgba(0, 0, 0, 0.5);
color: white;
border: none;
border-radius: 5px;
font-size: 18px;
line-height: 30px;
text-align: center;
cursor: pointer;
z-index: 10;
transition: background-color 0.2s;
}
.video-popup-mute-btn:hover {
background-color: rgba(0, 0, 0, 0.8);
}
Пример страницы с видео
Текущий URL:
Видео должно показываться 1 раз в 12 часов. И не показываться на URL, начинающихся с /bitrix/ или /admin/.
Прокрутите вниз.
...
Чтобы протестировать временной интервал, можно очистить LocalStorage (ключ `videoPopupLastShownTime`) или изменить `SHOW_INTERVAL_HOURS` на очень маленькое значение.
...
Еще контент...
<!-- Блок с видео -->
Ваш браузер не поддерживает тег video.
×
🔇
document.addEventListener('DOMContentLoaded', function() {
const videoPopup = document.getElementById('videoPopup');
const videoElement = document.getElementById('myPopupVideo');
const closeButton = document.getElementById('videoPopupClose');
const muteButton = document.getElementById('videoPopupMute');
// --- НАСТРОЙКИ ---
const SHOW_INTERVAL_HOURS = 12; // Показывать раз в N часов
const URL_EXCLUSIONS = [ // Список URL-ов для исключения показа (пути)
'/bitrix/', // Исключает все, что начинается с /bitrix/
'/admin/', // Исключает все, что начинается с /admin/
'/cart/', // Пример: исключить /cart/ и /cart/checkout/
// '/specific-page.html' // Пример для точного совпадения
];
const LOCAL_STORAGE_KEY = 'videoPopupLastShownTime';
const POPUP_DELAY_MS = 5000; // 5 секунд задержка перед показом
const MOBILE_MAX_WIDTH = 768; // Максимальная ширина для определения мобильного
// --- КОНЕЦ НАСТРОЕК ---
// Для отладки: отображаем текущий URL
const currentUrlDisplay = document.getElementById('currentUrlDisplay');
if (currentUrlDisplay) {
currentUrlDisplay.textContent = window.location.pathname;
}
// Функция проверки, является ли текущий URL исключением
function isUrlExcluded() {
const currentPath = window.location.pathname;
for (const exclusionPath of URL_EXCLUSIONS) {
if (currentPath.startsWith(exclusionPath)) {
console.log(`Видео не будет показано: URL "${currentPath}" соответствует исключению "${exclusionPath}".`);
return true;
}
}
return false;
}
// Функция проверки, можно ли показывать видео на основе времени
function canShowVideoByTime() {
const lastShownTimestamp = localStorage.getItem(LOCAL_STORAGE_KEY);
if (!lastShownTimestamp) {
return true; // Никогда не показывали, можно показать
}
const intervalMilliseconds = SHOW_INTERVAL_HOURS * 60 * 60 * 1000;
const timeSinceLastShown = Date.now() - parseInt(lastShownTimestamp, 10);
if (timeSinceLastShown >= intervalMilliseconds) {
return true; // Прошло достаточно времени
} else {
const hoursRemaining = ((intervalMilliseconds - timeSinceLastShown) / (60 * 60 * 1000)).toFixed(1);
console.log(`Видео не будет показано: еще не прошло ${SHOW_INTERVAL_HOURS} часов. Осталось: ${hoursRemaining} ч.`);
return false;
}
}
// Определяем, мобильное ли устройство
const isMobile = window.matchMedia(`(max-width: ${MOBILE_MAX_WIDTH}px)`).matches;
// --- ОСНОВНАЯ ЛОГИКА РЕШЕНИЯ О ПОКАЗЕ ---
if (isMobile) {
console.log("Мобильное устройство. Видео не будет загружено и показано.");
if (videoPopup) videoPopup.remove(); // Полностью убираем элемент
return; // Завершаем работу скрипта для попапа
}
if (isUrlExcluded()) {
// Сообщение уже выведено в isUrlExcluded
if (videoPopup) videoPopup.remove();
return;
}
if (!canShowVideoByTime()) {
// Сообщение уже выведено в canShowVideoByTime
if (videoPopup) videoPopup.remove();
return;
}
// Если все проверки пройдены, готовим и показываем видео
console.log("Все условия для показа видео выполнены. Готовим видео...");
window.addEventListener('load', function() {
// Устанавливаем источники видео
const sources = videoElement.getElementsByTagName('source');
for (let i = 0; i < sources.length; i++) {
if (sources[i].dataset.src) {
sources[i].src = sources[i].dataset.src;
}
}
videoElement.load(); // Инициируем загрузку видео
// Задержка перед показом и воспроизведением
setTimeout(function() {
if (videoPopup) { // Проверяем, что элемент еще существует
videoPopup.style.display = 'block';
// Сохраняем время показа ТОЛЬКО ПОСЛЕ ФАКТИЧЕСКОГО ПОКАЗА
localStorage.setItem(LOCAL_STORAGE_KEY, Date.now().toString());
console.log(`Видео показано. Время показа записано: ${new Date().toLocaleString()}`);
videoElement.play().catch(error => {
console.warn("Autoplay видео был предотвращен браузером:", error);
});
}
}, POPUP_DELAY_MS);
});
// --- ОБРАБОТЧИКИ КНОПОК (только если видео инициализировано) ---
if (closeButton && videoPopup) { // Убедимся, что videoPopup не был удален
closeButton.addEventListener('click', function() {
videoPopup.style.display = 'none';
videoElement.pause();
});
}
if (muteButton && videoElement && videoPopup) { // Убедимся, что videoPopup не был удален
muteButton.addEventListener('click', function() {
if (videoElement.muted) {
videoElement.muted = false;
muteButton.textContent = '🔊';
muteButton.setAttribute('aria-label', 'Выключить звук');
} else {
videoElement.muted = true;
muteButton.textContent = '🔇';
muteButton.setAttribute('aria-label', 'Включить звук');
}
});
// Инициализация иконки кнопки звука
if (videoElement.muted) {
muteButton.textContent = '🔇';
muteButton.setAttribute('aria-label', 'Включить звук');
} else {
muteButton.textContent = '🔊';
muteButton.setAttribute('aria-label', 'Выключить звук');
}
}
});
`
Ключевые изменения и пояснения:
-
Настройки в начале скрипта:
<li>
SHOW_INTERVAL_HOURS: Устанавливает интервал в часах.
-
URL_EXCLUSIONS: Массив строк. Каждая строка — это начало пути URL, на котором видео не должно показываться.
<li>
/bitrix/ будет соответствовать /bitrix/admin/index.php, /bitrix/components/sale.order/ и т.д.
-
/cart/ будет соответствовать /cart/ и /cart/checkout/ и т.д.
-
Если нужно точное совпадение (например, только /exact-page.html, а не /exact-page.html?param=1), то логику isUrlExcluded нужно будет усложнить для проверки полного window.location.pathname + window.location.search или использовать регулярные выражения. Текущая реализация с startsWith покрывает сценарий "папки и подпапки".
-
LOCAL_STORAGE_KEY: Имя ключа в localStorage.
-
MOBILE_MAX_WIDTH: Порог ширины для определения мобильного устройства.
-
Функция isUrlExcluded():
<li>
Получает текущий путь window.location.pathname.
-
Проходит по массиву URL_EXCLUSIONS.
-
Использует currentPath.startsWith(exclusionPath) для проверки, начинается ли текущий путь с одного из шаблонов исключения.
-
Функция canShowVideoByTime():
<li>
Читает время последнего показа из localStorage.
-
Если записи нет, значит, видео еще не показывали — можно показывать.
-
Если запись есть, сравнивает текущее время с временем последнего показа + интервал.
-
Основная логика принятия решения:
<li>
Сначала идет проверка на isMobile.
-
Затем проверка isUrlExcluded().
-
Затем проверка canShowVideoByTime().
-
Если хотя бы одно из этих условий предписывает не показывать видео, то элемент videoPopup удаляется из DOM (videoPopup.remove()), и скрипт прекращает дальнейшую работу с попапом. Это гарантирует, что видео не только не покажется, но и не будет загружено.
-
Если все проверки пройдены, скрипт продолжает загрузку и показ видео.
-
Запись времени показа:
<li>
localStorage.setItem(LOCAL_STORAGE_KEY, Date.now().toString()); вызывается только после того, как видео фактически отобразилось на странице (внутри setTimeout после videoPopup.style.display = 'block';). Это важно, чтобы не записывать "показ", если пользователь закрыл вкладку до истечения 5-секундной задержки.
-
Обработчики кнопок:
<li>
Добавлены проверки if (videoPopup) перед добавлением обработчиков, так как videoPopup мог быть удален, если условия показа не выполнены.
Тестирование:
-
Время: Откройте страницу. Видео должно появиться. Обновите — не должно. Чтобы сбросить, очистите localStorage (в Инструментах разработчика > Application > Local Storage, найдите ваш сайт и удалите ключ videoPopupLastShownTime) или временно измените SHOW_INTERVAL_HOURS на очень маленькое значение (например, 0.001).
-
URL-исключения: Перейдите на URL, который должен быть исключен (например, если ваш сайт на localhost, попробуйте [http://localhost/bitrix/test.html)](http://localhost/bitrix/test.html)). Видео не должно появиться. Перейдите на другой URL — должно (с учетом времени).
-
Мобильные: Проверьте в режиме эмуляции мобильного устройства.
Этот скрипт предоставляет надежный контроль над показом вашего видео-попапа.