2016-01-30 20 views
8

Mam wspólnego esceario serviceworker, w którym chcę złapać powiadomienie kliknij i skoncentruj kartę, z której pochodzi powiadomienie. Jednak klienci zmienna jest zawsze pusty, jego długość wynosi 0karta focus serviceworkers: klienci są pusta na notificationclick

console.log("sw startup"); 
 
self.addEventListener('install', function (event) { 
 
    console.log("SW installed"); 
 
}); 
 

 
self.addEventListener('activate', function (event) { 
 
    console.log("SW activated"); 
 
}); 
 
self.addEventListener("notificationclick", function (e) { 
 
    // Android doesn't automatically close notifications on click 
 
    console.log(e); 
 
    e.notification.close(); 
 
    
 
    // Focus tab if open 
 
    e.waitUntil(clients.matchAll({ 
 
     type: 'window' 
 
    }).then(function (clientList) { 
 
     console.log("clients:" + clientList.length); 
 
     for (var i = 0; i < clientList.length; ++i) { 
 
      var client = clientList[i]; 
 
      if (client.url === '/' && 'focus' in client) { 
 
       return client.focus(); 
 
      } 
 
     } 
 

 
     if (clients.openWindow) { 
 
      return clients.openWindow('/'); 
 
     } 
 
    })); 
 
    
 
});

I rejestracja jest to jedno:

this.doNotify = function (notification) {  
 
     if ('serviceWorker' in navigator) { 
 
      navigator.serviceWorker.register('sw.js').then(function (reg) { 
 
       
 
       requestCreateNotification(notification, reg); 
 
      }, function (err) { 
 
       console.log('sw reg error:' + err); 
 
      }); 
 
     } 
 
    ... 
 
    }

chrome: // ServiceWorker -internals/output pokazuje, że rejestracja i instalacja są w porządku. Jednak po wysłaniu powiadomienia lista ClientList jest pusta. Próbowałem usunąć typ filtra: "okno", ale wynik jest nadal taki sam. Ponieważ klienci są pusta, nowe okno jest zawsze otwarte. Co ja robię źle?

+0

Nie znam powodu ... co jeśli otworzę kolejną kartę lub odświeżę stronę, wykryję klienta. Więc przypuszczam, że musimy odświeżyć stronę, aby zaczęła wykrywać klientów? – moarra

Odpowiedz

16

Podejrzenie we własnym komentarzu jest poprawne. Strona jest kontrolowana przez pracownika serwisu podczas nawigacji do miejsca pochodzenia, w którym pracownik serwisu jest zarejestrowany pod numerem. Tak więc pierwotne ładowanie strony, które faktycznie inicjuje pracownika usługi, nie jest kontrolowane. Dlatego pracownik odnajduje twoją kartę po odwiedzeniu z nową kartą lub odświeżeniem.

Jednak (jak zauważa Jeff Posnick w komentarzach), można uzyskać niekontrolowane strony w następujący sposób: ServiceWorkerClients.matchAll({includeUncontrolled: true, type: 'window'}).

+6

Alternatywnie, ['ServiceWorkerClients.matchAll ({includeUncontrolled: true, type: 'window'})'] (https://developer.mozilla.org/en-US/docs/Web/API/Clients/matchAll) da odsyłasz obiekty 'Client', które odpowiadają stronom, które nie są jeszcze kontrolowane. (Jeśli chcesz, edytuj swoją odpowiedź, aby uwzględnić te informacje, nie zamierzam tego robić). –

+0

Myślę, że odpowiedź @ brendana zakończona twoją odpowiedzią jest prawidłowa! – moarra

+0

Dzięki Jeff, nie wiedziałem o tym. Zaktualizuje wpis. –

1

Postaraj się, aby pracownik serwisu natychmiast zgłosił roszczenie do strony. Np .:

self.addEventListener('install', event => event.waitUntil(self.skipWaiting())); 

self.addEventListener('activate', event => event.waitUntil(self.clients.claim())); 

przypadku bardziej skomplikowanego przykładu patrz https://serviceworke.rs/immediate-claim.html.