Multiple event handling

Okay so since my professor told me about this article Handling Events for Many Elements

I want to rewrite some of my old Javascript which apparently uses “bad practice”

HTML

<div id="voteParent">
    <input id="vote1" type="radio" name="voting" value="1">
    <label for="vote1">Vote 1</label>
    <input id="vote2" type="radio" name="voting" value="2">
    <label for="vote2">Vote 2</label>
    <input id="vote3" type="radio" name="voting" value="3">
    <label for="vote3">Vote 3</label>
    <input id="vote4" type="radio" name="voting" value="4">
    <label for="vote4">Vote 4</label>
    <input id="vote5" type="radio" name="voting" value="5">
    <label for="vote5">Vote 5</label>
</div>

Old javascript

function starRating() {
    var vote = document.getElementsByClassName('vote');
    var voteL = vote.length;
    for (let i = 0; i < voteL; i++) {
        let voteValue = vote[i].value;
        vote[i].addEventListener('click', function () {
            var imgValue = document.getElementById("imgValue").value;
            newImage(voteValue, imgValue, checked, "rating");
            console.log(vote[i].value);
            if (document.getElementById("globalRating")) {
                var globalRating = document.getElementById("globalRating");
                if (hasClass(globalRating, "leftIn")) {
                    globalRating.classList.remove("leftIn");
                    globalRating.classList.add("leftOut");
                }
            }
        });
    }
}

The new Javascript i am working on

    var voteParent = document.querySelector("#voteParent");
    voteParent.addEventListener("click", starRating, false);
    
    
    function starRating(e){
        if(e.target !== e.currentTarget){
            var clickedVote = e.target.value;
            alert("Target er = " + clickedVote);
        }
        
        e.stopPropagation();
    }

But my problem here is that the code tries to take the value from both the label and the input field, what do i do here so that when i click the label it does only store the value of the input?

Okay i made some changes to the HTML

<div id="voteParent">
    <input id="vote1" type="radio" name="voting" value="1">
    <input id="vote2" type="radio" name="voting" value="2">
    <input id="vote3" type="radio" name="voting" value="3">
    <input id="vote4" type="radio" name="voting" value="4">
    <input id="vote5" type="radio" name="voting" value="5">
</div>
            <label for="vote1">Vote 1</label>
            <label for="vote2">Vote 2</label>
            <label for="vote3">Vote 3</label>
            <label for="vote4">Vote 4</label>
            <label for="vote5">Vote 5</label>

Now it works perfect, and the inputs wount be visible anyway, but is this considered the proper approach?

labels are weird in that they act as a surrogate for the items they’re labeling. But at the same time, they act as their own entity. So what’s happening here is that when you click on the label, you’re ending up with 2 click events, one for the label and one for the input its for. This is why you’re getting the value alerted for each.

While the change in HTML fixes your problem, because you’re not getting click events for the labels anymore (just those that the label forward on to the inputs), you don’t always have the luxury of changing the HTML structure to fit your needs.

Instead, an alternate approach would be to perform some additional filtering in the event handler. You’re already checking to see if the target !== currentTarget (meaning ignore if voteParent was clicked directly instead of one of its children). With the first HTML structure, you could also include a filter to ignore the label elements, or inversely only target input elements. In fact if you look for inputs directly, you won’t need to the target/currentTarget comparison anymore either.

    function starRating(e){
        if(e.target.tagName === 'INPUT'){
            // ...