NoteJS/public/mobile-install-test.html
Fovway 091fc6cc1e Обновлены мета-теги и улучшена функциональность PWA
- Оптимизированы мета-теги в index.html и test-pwa.html для лучшей поддержки PWA.
- Улучшена структура кода с использованием многострочных атрибутов для мета-тегов.
- Обновлен сервисный работник для более эффективного кэширования и обработки запросов.
- Добавлены новые функции в pwa.js для управления установкой и обновлением PWA.
2025-10-20 12:29:43 +07:00

231 lines
7.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Тест установки PWA на мобильном</title>
<link rel="manifest" href="/manifest.json" />
<link rel="icon" href="/icon.svg" />
<style>
body {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.btn {
background: #007bff;
color: white;
border: none;
padding: 12px 24px;
border-radius: 5px;
cursor: pointer;
margin: 10px 5px;
font-size: 16px;
}
.btn:hover {
background: #0056b3;
}
.btn:disabled {
background: #ccc;
cursor: not-allowed;
}
.info {
background: #e7f3ff;
border: 1px solid #b3d9ff;
padding: 15px;
border-radius: 5px;
margin: 15px 0;
}
.success {
background: #d4edda;
border-color: #c3e6cb;
color: #155724;
}
.warning {
background: #fff3cd;
border-color: #ffeaa7;
color: #856404;
}
.error {
background: #f8d7da;
border-color: #f5c6cb;
color: #721c24;
}
.status {
margin: 10px 0;
padding: 10px;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="container">
<h1>📱 Тест установки PWA на мобильном</h1>
<div class="info">
<h3>Инструкции:</h3>
<p>1. Откройте эту страницу на мобильном устройстве</p>
<p>2. Должен появиться нативный баннер установки браузера</p>
<p>3. Если баннер не появился, используйте кнопки ниже</p>
</div>
<div id="status" class="status"></div>
<div>
<button id="install-btn" class="btn" disabled>
Установить приложение
</button>
<button id="show-banner-btn" class="btn">Показать баннер</button>
<button id="check-status-btn" class="btn">Проверить статус</button>
</div>
<div id="debug-info" class="info" style="margin-top: 20px">
<h3>Отладочная информация:</h3>
<div id="debug-content"></div>
</div>
</div>
<script>
let deferredPrompt;
const statusDiv = document.getElementById("status");
const installBtn = document.getElementById("install-btn");
const showBannerBtn = document.getElementById("show-banner-btn");
const checkStatusBtn = document.getElementById("check-status-btn");
const debugContent = document.getElementById("debug-content");
function updateStatus(message, type = "info") {
statusDiv.textContent = message;
statusDiv.className = `status ${type}`;
}
function updateDebugInfo() {
const info = {
userAgent: navigator.userAgent,
isMobile:
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
),
hasDeferredPrompt: !!deferredPrompt,
isPWAInstalled: window.matchMedia("(display-mode: standalone)")
.matches,
isOnline: navigator.onLine,
hasServiceWorker: "serviceWorker" in navigator,
};
debugContent.innerHTML = Object.entries(info)
.map(([key, value]) => `<strong>${key}:</strong> ${value}`)
.join("<br>");
}
// Обработка события beforeinstallprompt
window.addEventListener("beforeinstallprompt", (e) => {
console.log("beforeinstallprompt событие получено");
// На мобильных устройствах позволяем браузеру показать нативный баннер
const isMobile =
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
) ||
(navigator.maxTouchPoints && navigator.maxTouchPoints > 2) ||
window.matchMedia("(max-width: 768px)").matches;
if (!isMobile) {
e.preventDefault();
updateStatus(
"Десктоп: preventDefault() вызван, показываем кастомную кнопку",
"warning"
);
} else {
updateStatus(
"Мобильное устройство: разрешаем нативный баннер установки",
"success"
);
}
deferredPrompt = e;
installBtn.disabled = false;
updateDebugInfo();
});
// Обработка успешной установки
window.addEventListener("appinstalled", () => {
console.log("PWA установлено успешно");
updateStatus("Приложение установлено успешно!", "success");
installBtn.disabled = true;
deferredPrompt = null;
updateDebugInfo();
});
// Кнопка установки
installBtn.addEventListener("click", async () => {
if (deferredPrompt) {
updateStatus("Показываем баннер установки...", "info");
deferredPrompt.prompt();
const choiceResult = await deferredPrompt.userChoice;
if (choiceResult.outcome === "accepted") {
updateStatus("Пользователь установил приложение!", "success");
} else {
updateStatus("Пользователь отклонил установку", "warning");
}
deferredPrompt = null;
installBtn.disabled = true;
} else {
updateStatus("Баннер установки недоступен", "error");
}
updateDebugInfo();
});
// Кнопка показа баннера
showBannerBtn.addEventListener("click", () => {
if (deferredPrompt) {
updateStatus("Принудительно показываем баннер...", "info");
deferredPrompt.prompt();
} else {
updateStatus(
"Баннер установки недоступен. Попробуйте перезагрузить страницу.",
"error"
);
}
});
// Кнопка проверки статуса
checkStatusBtn.addEventListener("click", () => {
updateDebugInfo();
if (deferredPrompt) {
updateStatus("Баннер установки доступен", "success");
} else {
updateStatus("Баннер установки недоступен", "warning");
}
});
// Инициализация
updateDebugInfo();
updateStatus("Ожидание события beforeinstallprompt...", "info");
// Регистрация Service Worker
if ("serviceWorker" in navigator) {
navigator.serviceWorker
.register("/sw.js")
.then((registration) => {
console.log("SW зарегистрирован:", registration);
updateStatus("Service Worker зарегистрирован", "success");
})
.catch((error) => {
console.log("Ошибка регистрации SW:", error);
updateStatus("Ошибка регистрации Service Worker", "error");
});
}
</script>
</body>
</html>