Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Problem using querySelector with the filter() function

I tried to create a function that will change the background-color of all class-list items whenever a span of the specified className is hovered over.

Problems are:

  1. It works only whenever a single <span> was hovered – while I need it to happen whenever any <span> is hovered.

    MEDevel.com: Open-source for Healthcare and Education

    Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

    Visit Medevel

  2. It does not work with the last group of spans for some reason.

I assume there are much better ways to have written the code – sorry, I am new to JavaScript.

Thank you very much!

NOTE: The NEW ATTEMPT block of code is a failed attempt that has nothing to do with the shown effects.

The codes:

const array = [...document.getElementsByClassName('important')];
console.log(array);
console.log('---- ---- ---- ----');

// NEW ATTEMPT:

// NOTE: I copied that one from another code which had worked perfectly;
// I.E.: element.filter(item => (item !== e.target));

for (let i = 0; i < array.length; i++) {
    array[i].onmouseover = (e) => {
        console.log(`block ${i} was hovered over.`);

        // const arrayBlock = e.target;
        // arrayBlock.id = ``;

        let marking = array.filter(item => (item.querySelectorAll === `span.color-A${i}`));

        for (let all of marking) {
            all.style.backgroundColor = "red";
        };
    }
};

// NEW ATTEMPT ^^

// OLD ATTEMPT:

const markerContainer = document.getElementById('marker-container'); // Created because 'querySelector' couldn't be set upon const 'array';
console.log(markerContainer.children);
console.log('---- ---- ---- ----');

for (let i = 0; i < array.length; i++) {
    const arrayBlock = markerContainer.querySelector(`.block-A${i}`);
    
    console.log(arrayBlock);
    console.log('---- ---- ---- ----');

    const marking = arrayBlock.querySelectorAll(`span.color-A${i}`);

    console.log(marking);
    console.log('---- ---- ---- ----');

    marking[i].onmouseover = () => { // GETS AN ERROR: "TypeError: Cannot set properties of undefined (setting 'onmouseover')";
        for (let all of marking) {
            all.classList.remove(`A${i}-leave`);
            all.classList.add(`A${i}-enter`);
        };
    }

    marking[i].onmouseout = () => {
        for (let all of marking) {
            all.classList.remove(`A${i}-enter`);
            all.classList.add(`A${i}-leave`);
        };
    }
};

// OLD ATTEMPT ^^
.color-A0 {
    background-color: white;
    color: black;
}

.A0-enter {
    animation: A0-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A0-enter {
    0% {
        background-color: red;
        color: black;
    }

    100% {
        background-color: red;
        color: white;
    }
}

.A0-leave {
    animation: A0-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A0-leave {
    0% {
        color: black;
        background-color: red;
    }

    100% {
        background-color: white;
    }
}

.color-A1 {
    background-color: white;
    color: black;
}

.A1-enter {
    animation: A1-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A1-enter {
    0% {
        background-color: blue;
        color: black;
    }

    100% {
        background-color: blue;
        color: white;
    }
}

.A1-leave {
    animation: A1-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A1-leave {
    0% {
        color: black;
        background-color: blue;
    }

    100% {
        background-color: white;
    }
}

.color-A2 {
    background-color: white;
    color: black;
}

.A2-enter {
    animation: A2-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A2-enter {
    0% {
        background-color: green;
        color: black;
    }

    100% {
        background-color: green;
        color: white;
    }
}

.A2-leave {
    animation: A2-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A2-leave {
    0% {
        color: black;
        background-color: green;
    }

    100% {
        background-color: white;
    }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Document</title>

    <style>
        body {
            text-align: left;
            padding-top: 10%;
            padding-left: 10%;

            font-family: sans-serif;
            font-size: 40px;
        }
    </style>

    <link rel="stylesheet" href="a.css">
</head>

<body>
    <div id="marker-container">

        <span class="important block-A0">
            <p>

                <span class="color-A0">
                    Important Text Number A1 (Related to: Red)</span>
                -
                <span class="color-A0">
                    Important Text Number A2 (Related to: Red)</span>

                BLAH BLAH BLAH

                <span class="color-A0">
                    Important Text Number A3 (Related to: Red)</span>

                BLAH BLAH BLAH
                -
                <span class="color-A0">
                    Important Text Number A4 (Related to: Red)</span>

                Summary.

            </p>
        </span>

        <span class="important block-A1">
            <p>

                BLAH BLAH BLAH

                <span class="color-A1">
                    Important Text Number B1 (Related to: Red)</span>
                -
                BLAH BLAH BLAH

                <span class="color-A1">
                    Important Text Number B2 (Related to: Red)</span>

                Summary.

            </p>
        </span>

        <span class="important block-A2">
            <p>

                <span class="color-A2">
                    Important Text Number C1 (Related to: Red)</span>

                BLAH BLAH BLAH

                -
                BLAH BLAH BLAH

                <span class="color-A2">
                    Important Text Number C2 (Related to: Red)</span>

                Summary.

            </p>
        </span>

    </div>

    <script src="a.js"></script>
</body>

</html>

>Solution :

let marking = array.filter(item => (item.querySelectorAll === `span.color-A${i}`));

This line will not work as expected sine querySelectoAll isn’t called as a function.

But since you already have the DOM element you need (array[1]), you can search for childern inside it with querySelector and then style those on mouse enter/leave.

We also use a css attribute selector so we can use * to match all color-A classes:

[ ...array[i].querySelectorAll('span[class *= color-A]') ]

Original snippet:

const array = [...document.getElementsByClassName('important')];

for (let i = 0; i < array.length; i++) {
    array[i].onmouseover = (e) => {        
        for (let j of [ ...array[i].querySelectorAll('span[class *= color-A]') ]) {
            j.style.backgroundColor = "red";
        };
    }
    array[i].onmouseleave = (e) => {        
        for (let j of [ ...array[i].querySelectorAll('span[class *= color-A]') ]) {
            j.style.backgroundColor = "unset";
        };
    }
};
.color-A0 {
    background-color: white;
    color: black;
}

.A0-enter {
    animation: A0-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A0-enter {
    0% {
        background-color: red;
        color: black;
    }

    100% {
        background-color: red;
        color: white;
    }
}

.A0-leave {
    animation: A0-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A0-leave {
    0% {
        color: black;
        background-color: red;
    }

    100% {
        background-color: white;
    }
}

.color-A1 {
    background-color: white;
    color: black;
}

.A1-enter {
    animation: A1-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A1-enter {
    0% {
        background-color: blue;
        color: black;
    }

    100% {
        background-color: blue;
        color: white;
    }
}

.A1-leave {
    animation: A1-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A1-leave {
    0% {
        color: black;
        background-color: blue;
    }

    100% {
        background-color: white;
    }
}

.color-A2 {
    background-color: white;
    color: black;
}

.A2-enter {
    animation: A2-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A2-enter {
    0% {
        background-color: green;
        color: black;
    }

    100% {
        background-color: green;
        color: white;
    }
}

.A2-leave {
    animation: A2-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A2-leave {
    0% {
        color: black;
        background-color: green;
    }

    100% {
        background-color: white;
    }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Document</title>

    <style>
        body {
            text-align: left;
            padding-top: 10%;
            padding-left: 10%;

            font-family: sans-serif;
            font-size: 40px;
        }
    </style>

    <link rel="stylesheet" href="a.css">
</head>

<body>
    <div id="marker-container">

        <span class="important block-A0">
            <p>

                <span class="color-A0">
                    Important Text Number A1 (Related to: Red)</span>
                -
                <span class="color-A0">
                    Important Text Number A2 (Related to: Red)</span>

                BLAH BLAH BLAH

                <span class="color-A0">
                    Important Text Number A3 (Related to: Red)</span>

                BLAH BLAH BLAH
                -
                <span class="color-A0">
                    Important Text Number A4 (Related to: Red)</span>

                Summary.

            </p>
        </span>

        <span class="important block-A1">
            <p>

                BLAH BLAH BLAH

                <span class="color-A1">
                    Important Text Number B1 (Related to: Red)</span>
                -
                BLAH BLAH BLAH

                <span class="color-A1">
                    Important Text Number B2 (Related to: Red)</span>

                Summary.

            </p>
        </span>

        <span class="important block-A2">
            <p>

                <span class="color-A2">
                    Important Text Number C1 (Related to: Red)</span>

                BLAH BLAH BLAH

                -
                BLAH BLAH BLAH

                <span class="color-A2">
                    Important Text Number C2 (Related to: Red)</span>

                Summary.

            </p>
        </span>

    </div>

    <script src="a.js"></script>
</body>

</html>

Snippet 2 based on OP’s comment.

If you want to style all his syblings, you can use event.parentNode to get the parent of current span, then use querySelector to get all his actual spans childs to color.

const allClasses = [...document.querySelectorAll('span[class *= color-A]')];

for (let c of allClasses) {
    c.onmouseover = (e) => {
        let parent = e.target.parentNode;
        let spansInParent = [ ...parent.querySelectorAll('span[class *= color-A]') ]
        
        for (let ss of spansInParent) {
            ss.style.background = 'red'
        }
    }
    c.onmouseout = () => {
        for (let ss of allClasses) {
            ss.style.background = 'unset'
        }
    }
   
}
.color-A0 {
    background-color: white;
    color: black;
}

.A0-enter {
    animation: A0-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A0-enter {
    0% {
        background-color: red;
        color: black;
    }

    100% {
        background-color: red;
        color: white;
    }
}

.A0-leave {
    animation: A0-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A0-leave {
    0% {
        color: black;
        background-color: red;
    }

    100% {
        background-color: white;
    }
}

.color-A1 {
    background-color: white;
    color: black;
}

.A1-enter {
    animation: A1-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A1-enter {
    0% {
        background-color: blue;
        color: black;
    }

    100% {
        background-color: blue;
        color: white;
    }
}

.A1-leave {
    animation: A1-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A1-leave {
    0% {
        color: black;
        background-color: blue;
    }

    100% {
        background-color: white;
    }
}

.color-A2 {
    background-color: white;
    color: black;
}

.A2-enter {
    animation: A2-enter 0.4s ease 0s 1 normal forwards;
}

@keyframes A2-enter {
    0% {
        background-color: green;
        color: black;
    }

    100% {
        background-color: green;
        color: white;
    }
}

.A2-leave {
    animation: A2-leave 0.4s ease 0s 1 normal forwards;
}

@keyframes A2-leave {
    0% {
        color: black;
        background-color: green;
    }

    100% {
        background-color: white;
    }
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Document</title>

    <style>
        body {
            text-align: left;
            padding-top: 10%;
            padding-left: 10%;

            font-family: sans-serif;
            font-size: 40px;
        }
    </style>

    <link rel="stylesheet" href="a.css">
</head>

<body>
    <div id="marker-container">

        <span class="important block-A0">
            <p>

                <span class="color-A0">
                    Important Text Number A1 (Related to: Red)</span>
                -
                <span class="color-A0">
                    Important Text Number A2 (Related to: Red)</span>

                BLAH BLAH BLAH

                <span class="color-A0">
                    Important Text Number A3 (Related to: Red)</span>

                BLAH BLAH BLAH
                -
                <span class="color-A0">
                    Important Text Number A4 (Related to: Red)</span>

                Summary.

            </p>
        </span>

        <span class="important block-A1">
            <p>

                BLAH BLAH BLAH

                <span class="color-A1">
                    Important Text Number B1 (Related to: Red)</span>
                -
                BLAH BLAH BLAH

                <span class="color-A1">
                    Important Text Number B2 (Related to: Red)</span>

                Summary.

            </p>
        </span>

        <span class="important block-A2">
            <p>

                <span class="color-A2">
                    Important Text Number C1 (Related to: Red)</span>

                BLAH BLAH BLAH

                -
                BLAH BLAH BLAH

                <span class="color-A2">
                    Important Text Number C2 (Related to: Red)</span>

                Summary.

            </p>
        </span>

    </div>

    <script src="a.js"></script>
</body>

</html>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading