One way to generate a random color is to randomize the hue argument of the css hsl. This value is in degrees 0-360 (colorwheel). The other arguments can be randomized as well if you need random saturation and lightness… like this:
document.body.innerHTML+='click to randomize background color';
const col = `hsl(${Math.random()*360}deg,50%,50%)`
e.target.style.background= col;
}
};
document.body.addEventListener('click', e =>{
// combine as many actions as we want
[...e.target.classList].forEach(cls =>{
const action = actions[cls];
if(action !=null) action(e);
});
});
This snippet takes the ideas from yesterdays post and goes one level further. This associates behavior with class names, so the class names can be combined to mix and match behavior.
In this case, combining classes like this green circle noBorder moveDown sayHi randomBgColor will cause the element in question to “move down”, “say hi” and randomize its background color when it is clicked. Click the “Try it out” to get a better idea.
console.log('camelCase instead of kebab-case :D');
},
};
document.addEventListener('mousedown',(e)=>{
const action = actions[e.target.classList[0]];
if(action !=null) action(e);
});
This is a powerful little pattern for managing mouse/touch events. Rather than assigning many listeners, this snippet has one listener on the document. Anytime the page is clicked, we look at the event targets classList and use its first value as a key in an actions object.
I have used this or some variation of it many many times over the years. With a little customization it scales well into large projects. I always find myself on the fence about class naming conventions… kebab-case vs camelCase – probably because it just doesn’t matter that much. For large projects, each main section of the UI will have its own document.addEventListener just for organizational purposes.
Variations
The choice to use the first class as the key for the action is pretty arbitrary. Depending on how you like to set things up you could use the last value of the classList, the element id, the element name, or a custom data attribute etc… Like this:
// id
const action = actions[e.target.id];
// name
const action = actions[e.target.name];
// data attribute <button data-my-id="test">test</button>
JSON.stringify has two more arguments that allow for pretty printing and processing of the object in question. The second argument is a “replacer” function and the third argument is for indentation. Read more details here.
I’m thinking about adding a little fake console to the Snippet Zone Quick Editor – just whipped this up as a proof of concept – something like this should work…