由web worker访问dom

我变得疯狂,需要你的帮助。 我正在研究一个serviceworker项目,我正在处理一个javascript问题。 我有两个主要文件。 server.html文件,我在第52行调用外部service-worker.js文件。 这是我的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; }); });

这是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; }); 

在最后一行,我想在div“talker”中插入收到的消息。 但我总是得到错误service-worker.js:17 Uncaught ReferenceError:文档未定义

我小心翼翼,我在加载文档后加载了js-File。 现在我不知道自己做错了什么。 谢谢。

服务工作者 – 一般的Web工作者 – 根本无法直接访问DOM。 相反,让工作人员将信息发布到主线程,并让主线程中的代码根据需要更新DOM。 浏览器上的JavaScript的主题模型是,只有一个主UI线程(运行页面内代码的默认线程)可以访问DOM。 其他人被围住了。

此页面和此页面都讨论了服务工作者和客户端之间的消息传递。 这是一个非常简单的例子:

加载服务工作者的页面中的脚本:

 (function() { "use strict"; 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); }); } })(); 

service-worker.js

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

这取决于当前版本的Chrome和Firefox支持的event.source

或者,您可以使用event.source将消息发送到服务工作者的多个客户端,而不是使用self.clients.matchAll ; 再次在service-worker.js

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

matchAll接受一些过滤选项 。


你说你在上class时遇到了麻烦。 以下是Chrome和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); })); }); 

正如您所看到的,这是使用event.source版本,其上面注释了event.source版本。

如果我在两个窗口中运行它,每个窗口的每次刷新都会向其他窗口发送一条消息(因为我使用的是self.clients.matchAll …)。

服务工作者基于异步,根据文章,您无法使用服务工作访问DOM,以获取更多信息,请访问https://developers.google.com/web/fundamentals/primers/service-workers/