Заменить актив в сервисном работнике событием выборки
Я пытаюсь переключить таблицу стилей темы с моим сервисным работником.
Я создал тему для Jekyll (для использования со страницами GitHub) и хотел иметь возможность заменить темную тему на светлую ("выключить свет") и сделать ее согласованной.
Прямо сейчас это достигается за счет сохранения localstorage
и замена темы link
элемент в соответствии с этим.
проблема в том, что проверка происходит после извлечения оригинальной белой темы, так что пользователь видит вспышку белой темы, даже если localstorage
установить темную тему
Вот как он ведет себя в данный момент (кнопки находятся в правом верхнем углу): https://thatkookooguy.github.io/postmortem-demo/postmortem/002
после изменения темы попробуйте перейти на другую страницу. страница загружается с белой темой, а затем меняется на темную тему
Я думал, что могу решить эту проблему, переключив скрипт внутри сервисного работника, так как я могу addEventListener
к fetch
событие и замените его в цепочке обещаний другой выборкой.
Но код, похоже, не работает. Если я добавлю точку отладки в функцию обратного вызова события, она никогда не сработает (не на ресурсах и не на реальных выборках страниц)
HTML Head
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet prefetch' href='//fonts.googleapis.com/css?family=Fredoka+One|Righteous'>
<!-- THIS SHOULD BE INTERCEPTED BY THE SERVICE WORKER -->
<link id="bulma-theme" rel="stylesheet prefetch" href="//unpkg.com/bulmaswatch/default/bulmaswatch.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" type="text/css" href="{{ site.baseurl }}/assets/style.css" />
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('{{ site.baseurl }}/assets/sw.js')
.then(function() {
console.log("Service Worker Registered");
});
}
</script>
</head>
Сервисный код работника
importScripts('localforage.min.js');
// remember the theme
this.onmessage = function(msg) {
if (!msg.data.theme) {
return;
}
localforage.setItem('theme', msg.data.theme);
}
// replace link fetching with correct theme
this.addEventListener('fetch', function(event) {
console.log(event.request.url);
if (event.request.url.contains('/bulmaswatch/')) {
return localforage.getItem('theme')
.then(function(theme) {
if (theme === 'kb-dark-theme') {
let darkThemeRequest = new Request(request.url.replace('bulmaswatch/default/', 'bulmaswatch/superhero/'), {
method: request.method,
headers: request.headers,
mode: 'same-origin',
credentials: request.credentials,
redirect: 'manual'
});
return fetch(darkThemeRequest);
}
return fetch(event.request);
})
}
});
// Log SW installation
this.addEventListener('install', function(event) {
console.log('[SW]: installing....');
});
// Log SW activation
this.addEventListener('activate', function activator(event) {
console.log('[SW]: activate!');
});
При отладке в Chrome (и Chrome Canary, так как я слышал, что там улучшена поддержка отладки сервисных работников), обратный вызов на fetch
даже никогда не звонил. ни один запрос не был зарегистрирован.
Я вижу, что сервисный работник зарегистрирован и активен в инструментах разработчика Chrome. и я вижу, как другие события регистрируются в консоли.
Кроме того, при отладке и установке точки останова в начале скрипта это выглядит как bulmaswatch.min.css
был уже получен.
Есть идеи, что мне не хватает?:-)
Спасибо
1 ответ
Основная проблема связана с объемом вашего работника службы.
Когда я захожу на https://thatkookooguy.github.io/postmortem-demo/postmortem/002 и просматриваю панель "Приложение> Сервисные работники" в Chrome DevTools, я вижу, что у сервисного работника есть область действия: https://thatkookooguy.github.io/postmortem-demo/assets
и не контролирует клиентов.
Если вы переместите sw.js
файл из /assets/
подкаталог, и в каталог верхнего уровня для вашего сайта (который /postmortem-demo/
), а затем измените свой регистрационный код, чтобы отразить это, и тогда ваш обслуживающий работник сможет контролировать ваши клиентские страницы:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/postmortem-demo/sw.js');
}
(Это означает, что при локальной разработке вы также должны предоставлять своему веб-приложению префикс URL-адреса: /postmortem-demo/
чтобы соответствовать этому.)
Следующие ресурсы имеют больше информации о сфере обслуживания работника: