As web workers can't interact with the DOM, the idea here would be to handle all the computations in the web worker (i.e. p3.js) and the display updates should be handled on the other side, as they are locked in the UI thread, no matter what we do (afaik anyways).
isPrime would probably be relocated in p3.js as window is not available in the context of a worker.
A few things are broken in your code. Also you probably don't want to test with such a high value as 1e9 to find prime number with a non optimized algorithm, it might look like an irrelevant thing to say but when you want to test that something works, I'd suggest not going too crazy with the "siders" :D
So first things first, let's get rid of the DOM api call on the worker side. (note that I replaced 1+e9 with +1e9)
function problem3(){ var number = +1e9; for(var i=2;i<number;i++){ if(isPrime(i) && number%i==0) var maxPrime = i; } postMessage(maxPrime); }
Now, since p3.js is a different file in a different thread, you won't have access to any of the memory of your main script. Which means that isPrime is unavailable in the worker's context. Hopefully this has a straight forward solution as you can simply move the isPrime function to p3.js.
You are using onclick="startWorkerp3()" to attach your user control. It is generally recommended to user addEventListener, and in this particular case your worker will never start because of onclick's context handling
As an alternative, for instance it could look like this
<button id="start">Start Worker</button>
And in the main script file we need to relocate the code that was removed from the worker. From what I understand, you want to toggle the image visibility when your computation is sarted/over.
document.querySelector('#start').addEventListener('click', function () { document.getElementById('p_3').style.display = 'none'; startWorkerp3(); });
And when the worker has finished computing
w.onmessage = function(event) { document.getElementById("p3").innerHTML = event.data; document.getElementById("p_3").style.display = 'block'; };
In the end here is how it could like (I'm summing up so that you can copy/paste and test it easily). You will probably spot some little tweaks that I made, some of them can be ignored, anyways it would have been too long to explain every little thing.
HTML
<div> <button id="start">Start Worker</button> <button id="stop">Stop Worker</button> <img id="p_3" src="PROBLEM3.png" alt="PROBLEM3.png" style="display: none;"> <output id="p3"></output> </div>
JS
var w; document.querySelector('#start').addEventListener('click', function () { var img = document.getElementById('p_3'); img.style.display = 'none'; startWorkerp3(); }); document.querySelector('#stop').addEventListener('click', function () { if (w) { stopWorkerp3(); } }); function startWorkerp3() { if(typeof(Worker) !== "undefined") { if(typeof(w) == "undefined") { w = new Worker("p3.js"); } w.onmessage = function(event) { document.getElementById("p3").innerHTML = event.data; document.getElementById('p_3').style.display = 'block'; }; } else { document.getElementById("p3").innerHTML = "Sorry! No Web Worker support."; } w.postMessage('start'); } function stopWorkerp3() { w.terminate(); w = undefined; }
p3.js
onmessage = function (evt) { postMessage(problem3()); }; function problem3() { var number=100000; for(var i=2;i<number;i++){ if(number%i==0 && isPrime(i)) var maxPrime = i; } return maxPrime; } function isPrime(value) { for(var i = 2; i < value; i++) { if(value % i === 0) { return false; } } return value > 1; }