Search code examples
javascriptjqueryhtmlworkercss-variables

is it possible to update variable value from html worker file?


I'm learning about using worker files for a html page. I'm trying to update a css variable based on returned value from worker.js.

If I update the css variable within worker.addEventListener, color changes to yellow.

If I try to update the css variable outside of eventlistener, it doesn't do anything because mood_color is undefined.

Is it possible to assign value to variable from html worker?


HTML

    <style>
        :root {
            --mood-color: grey;
        }
    </style>

    <body>
        <h3 class="my_feelings" style="color: var(--mood-color)"> 
            My Feelings 
        <h3>
    </body>

jquery

    $(document).ready(function(){
        var worker = new Worker("/js/mood.js");
        var mood_color; 
        worker.addEventListener('message', function(e){
            mood_color = e.data;
            console.log(mood_color[0].color) // prints "yellow";

            // changes header color to yellow.
            $(".my_feelings").get(0).style.setProperty("--mood-color", mood_color); 

        });
        worker.postMessage("sunny");
        console.log(mood_color[0].color) // prints "undefined";

        // doesn't change mood color because mood_color is undefined
        $('.my_feelings').on('click', function(){
            $(".my_feelings").get(0).style.setProperty("--mood-color", mood_color); 

        });
    });

mood.js (html worker)

    var weather = [
        {"weather": "sunny", "mood": "happy", "color": "yellow"},
        {"weather": "rainy", "mood": "sad"}, "color": "blue"
    ];

    self.addEventListener('message', function(e) {
        var color = weather .filter(function(i, n){
            return i.weather == e.data;
        });
        self.postMessage(color);
    }, false);

Solution

  • There's a number of issues with your code. Aside from the syntax errors:

    mood_color isn't defined at that point because postMessage sends an asynchronous message. Since it's asynchronous, the response won't happen until later, well after that console.log runs.

    When mood_color is finally set, it's set to an array of objects (just one in this case), not a color, because this is what's passed in from the worker. Specifically, it's set to:

    [ { weather: 'sunny', mood: 'happy', color: 'yellow' } ]
    

    When you try to set the CSS variable to this, the array is coerced to the string "[object Object]" and the CSS variable is set to that. This is why the text ends up black instead of the grey you set it to in the CSS or the yellow you're trying to change it to. mood_color[0].color would get the actual color value.