Accès dom par le web

Je deviens fou et j’ai besoin de votre aide. Je travaille sur un projet de serviceworker et je traite un problème javascript. J’ai deux fichiers principaux. Le fichier server.html dans lequel j’appelle le fichier externe service-worker.js à la ligne 52 . Voici mon fichier server.html

  

PRESENTER

Nickname:


-->



$(document).ready(function() { console.log("jquery ready function"); $('#nick').focus(); $('#form-nick').submit(function(){ var form = $('#form-nick'); var data = form.serialize(); $.post('nicky.php', data, function(response) { if (response) { $('#nicky').show(); $('#nickname').text(response); $('#form-nick').hide(); $('.blue, .red, .lightblue').fadeIn(100); if('serviceWorker' in navigator){ // Register service worker navigator.serviceWorker.register('service-worker.js').then(function(reg){ console.log("SW registration succeeded. Scope is "+reg.scope); }).catch(function(err){ console.error("SW registration failed with error "+err); }); } } else { } }); return false; }); });

et voici le fichier service-worker.js

 // Install Service Worker self.addEventListener('install', function(event){ console.log('>> sw installed!'); }); // Service Worker Active self.addEventListener('activate', function(event){ console.log('>> sw activated!'); }); // Service Worker reveives message self.addEventListener('message', function(event){ console.log(event.data); send_message_to_all_clients(event.data); document.getElementById("talker").innerHTML = event.data; }); 

Dans la dernière ligne, je voudrais insérer le message reçu dans le div “talker”. Mais je reçois toujours l’erreur service-worker.js: 17 Uncaught ReferenceError: le document n’est pas défini

J’ai pris soin de charger le fichier js une fois le document chargé. Maintenant, je ne sais pas ce que je fais mal. Merci.

Les employés de service – les travailleurs Web en général – n’ont aucun access direct au DOM. Demandez au travailleur de publier les informations sur le thread principal et de laisser le code dans le thread principal mettre à jour le DOM, le cas échéant. Le modèle de lecture de JavaScript sur les navigateurs est qu’il n’ya qu’un seul thread principal de l’interface utilisateur (celui par défaut sur lequel le code de la page est exécuté), qui peut accéder au DOM. Les autres en sont exclus.

Cette page et cette page traitent toutes deux de la messagerie entre les opérateurs de services et les clients. Voici un exemple très simple:

Script dans la page de chargement du service worker:

 (function() { "use ssortingct"; if (!navigator.serviceWorker || !navigator.serviceWorker.register) { console.log("This browser doesn't support service workers"); return; } // Listen to messages from service workers. navigator.serviceWorker.addEventListener('message', function(event) { console.log("Got reply from service worker: " + event.data); }); // Are we being controlled? if (navigator.serviceWorker.controller) { // Yes, send our controller a message. console.log("Sending 'hi' to controller"); navigator.serviceWorker.controller.postMessage("hi"); } else { // No, register a service worker to control pages like us. // Note that it won't control this instance of this page, it only takes effect // for pages in its scope loaded *after* it's installed. navigator.serviceWorker.register("service-worker.js") .then(function(registration) { console.log("Service worker registered, scope: " + registration.scope); console.log("Refresh the page to talk to it."); // If we want to, we might do `location.reload();` so that we'd be controlled by it }) .catch(function(error) { console.log("Service worker registration failed: " + error.message); }); } })(); 

Et dans service-worker.js :

 self.addEventListener("message", function(event) { event.source.postMessage("Responding to " + event.data); }); 

Cela repose sur event.source , qui est pris en charge par les versions actuelles de Chrome et Firefox.

Sinon, au lieu d’utiliser event.source , vous pouvez envoyer un message à plusieurs clients d’un agent de service à l’aide de self.clients.matchAll ; à nouveau dans service-worker.js :

 self.addEventListener("message", function(event) { self.clients.matchAll().then(all => all.forEach(client => { client.postMessage("Responding to " + event.data); })); }); 

matchAll accepte certaines options de filtrage .


Vous avez dit que vous avez du mal à le faire fonctionner. Voici une version complète de ce qui fonctionne pour moi dans Chrome et Firefox:

service-worker.html :

     Service Worker   (Look in the console.)    

service-worker.js :

 self.addEventListener("message", function(event) { //event.source.postMessage("Responding to " + event.data); self.clients.matchAll().then(all => all.forEach(client => { client.postMessage("Responding to " + event.data); })); }); 

Comme vous pouvez le constater, c’est la version qui utilise self.clients.matchAll , avec la version commentée de event.source au-dessus.

Si j’exécute cela dans deux fenêtres, chaque actualisation de chaque fenêtre envoie un message aux autres fenêtres (car j’utilise self.clients.matchAll …).

L’agent de service est basé sur le principe asynchrone et, selon l’article, vous ne pouvez pas accéder au DOM en utilisant le service pour plus d’informations, consultez https://developers.google.com/web/fundamentals/primers/service-workers/