Reputation: 421
I'm working on offloading some url polling requests to a web worker. To do this, I need to fetch certain attributes from the DOM element of invokation, pass them into a url request, then update the original DOM element with the results. Since multiple DOM elements use this function to fetch updates, I need to pass through $(this)
or an equivalent unique identifier to ensure the correct element is updated.
I understand from questions such as "Passing objects to a web worker" and "Can I pass a jQuery object to a web worker" that this is not possible, so I am looking for a means to emulate this.
Here is a rough outline of my code:
//main.js
function update(){
var data = { 'id' : $(this).attr('itemid'),
'filter' : $(this).attr('filter')}
updatePoller.postMessage(data);
}
//worker.js
this.onmessage = function(e){
//format params from e.data
//make GET request to url
//when done...
postMessage(req.responseText);
}
//main.js (again)
updatePoller.onmessage = function(message){
//process response
//update child elements of $(this)
}
As you can see, I don't need to access $(this)
inside the web worker, but I need the reference once the request has returned in order to update the correct element. Are there any ways to pass a unique reference to a DOM element through a web worker?
Upvotes: 1
Views: 329
Reputation: 1074168
The usual way to uniquely identify an element when you can't use its reference is to use an id
. Alternately, you could use a data-*
attribute, but really id
s were made for this specific purpose.
So (see comments):
//main.js
var lastId = 0;
function update(){
// Assign ID if necessary
if (!this.id) {
++lastId;
this.id = "__auto" + lastId;
}
var data = { 'id' : $(this).attr('itemid'),
'filter' : $(this).attr('filter'),
'elementId': this.id}
updatePoller.postMessage(data);
}
//main.js (again)
updatePoller.onmessage = function(message){
// Use the `element` value sent back to look it up by ID:
$("#" + message.data.elementId).xyz();
}
If having all of those automatic globals (since id
values create automatic globals) bothers you, you could remove the ID when done with it:
//main.js (again)
updatePoller.onmessage = function(message){
var elm = $("#" + message.data.elementId);
if (elm.attr("id").startsWith("__auto")) { // auto ID?
elm.attr("id", ""); // remove it
}
elm.xyz();
}
or with less jQuery:
//main.js (again)
updatePoller.onmessage = function(message){
var elm = $("#" + message.data.elementId)[0];
if (elm && elm.id.startsWith("__auto")) {
elm.id = "";
}
$(elm).xyz();
}
Upvotes: 2