[英]Access dom by web worker
我變得瘋狂,需要你的幫助。 我正在研究一個serviceworker項目,我正在處理一個javascript問題。 我有兩個主要文件。 我在其中調用第52
行中的外部service-worker.js
文件的server.html
文件。 這是我的server.html
文件
<body>
<div class="container">
<h1>PRESENTER</h1>
<div id="nicky">Nickname: <span id="nickname"></span></div>
<form id="form-nick" name="form-nick" method="post" action="">
<div class="formelement">
<label name="labelnick" for="nick">Nickname:</label>
<input type="text" id="nick" name="nick">
<button type="submit">OK</button>
</div>
</form><br /><br />
<h1>--></h1><div id="talker"></div>
<button type="button" class="button blue" id="blue-display" disabled></button><br />
<button type="button" class="button red" disabled></button><br />
<button type="button" class="button lightblue" disabled></button>
</div> <!-- container -->
<script type="text/javascript">
$(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;
});
});
</script>
</body>
這是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);
}));
});
你說你在上班時遇到了麻煩。 以下是Chrome和Firefox中適合我的完整版本:
service-worker.html
:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Service Worker</title>
</head>
<body>
(Look in the console.)
<script>
(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);
});
}
})();
</script>
</body>
</html>
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);
}));
});
正如你所看到的,這是用的版本self.clients.matchAll
,與注釋掉event.source
版本上面。
如果我在兩個窗口中運行它,每個窗口的每次刷新都會向其他窗口發送一條消息(因為我使用的是self.clients.matchAll
...)。
服務工作者基於異步,根據文章,您無法使用服務來訪問DOM,以獲取更多信息,請訪問https://developers.google.com/web/fundamentals/primers/service-workers/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.