#compacting a javascript function

93 messages · Page 1 of 1 (latest)

normal venture
#

I'm doing a javascript function with event listener and i have to do the same thing for multiple html elements, is there a way to compact it without typing the same thing many times and only changing the id of the element?

#

i have to do this 6 times and i'd like to do it just 1 time and creating a function with the id as parameters, but i don't know if it's possible

normal venture
#

something like this

wooden ginkgo
#

should work

fallen grove
#

I mean if you are doing that, you should just pass event or e to the function instead of getting the same thing twice.

#

Also, can you copy paste your code instead of screenshot?

normal venture
normal venture
# fallen grove Also, can you copy paste your code instead of screenshot?

document.addEventListener('DOMContentLoaded', start);

function start(){

const vintage = document.getElementById("cate1");
const classico = document.getElementById("cate2");
const moderno = document.getElementById("cate3");
const lussuoso = document.getElementById("cate4");
const led = document.getElementById("cate5");
const plafoniera = document.getElementById("cate6");

vintage.addEventListener('mouseover', categorieOver("cat1"));
vintage.addEventListener('mouseout', categorieOut("cat1"));

classico.addEventListener('mouseover', categorieOver("cat2"));
classico.addEventListener('mouseout', categorieOut("cat2"));

moderno.addEventListener('mouseover', categorieOver("cat3"));
moderno.addEventListener('mouseout', categorieOut("cat3"));

lussuoso.addEventListener('mouseover', categorieOver("cat4"));
lussuoso.addEventListener('mouseout', categorieOut("cat4"));

led.addEventListener('mouseover', categorieOver("cat5"));
led.addEventListener('mouseout', categorieOut("cat5"));

plafoniera.addEventListener('mouseover', categorieOver("cat6"));
plafoniera.addEventListener('mouseout', categorieOut("cat6"));
}

function categorieOver(id){
document.getElementById(id).style.border = '10px solid black';
}
function categorieOut(id){
document.getElementById(id).style.border = '3px solid black';
}

fallen grove
#

plafoniera.addEventListener('mouseout',() => categorieOut("cat6"));

#

should be this

#
function categorieOver(e){
  e.target.style.border = '10px solid black';
}
fallen grove
normal venture
#

but it's not the same id

#

i dont know if i can use the same id

#

i put the over in the tag <a> and the border change in the <div> tag

#

can i put the over in the div?

normal venture
fallen grove
#

Can you make copy paste your code in jsfiddle?

normal venture
fallen grove
fallen grove
normal venture
normal venture
fallen grove
normal venture
#

how?

#

does this work?

fallen grove
#

I dont see the code

normal venture
#

now?

fallen grove
#

no

#

you should be able to share it without starting a collab session

#

did you save it?

normal venture
#

yes

#

how can i share?

fallen grove
#

just copy paste the link here

normal venture
#

ah ok

fallen grove
#

like I have this here

#

yeah, I can see it now

#

I don't see elements with id like cate2, cate3 etc

#

only cate1

normal venture
#

ah

#

ops

#

xd

#

it works now thank you

#

can i put the mouseover on the div instead of a?

fallen grove
#

yes

normal venture
#

ty

normal venture
#

no wait it doesnt work

#

now theres the over effect in the text too

#

not only the rectangular

normal venture
#

if i do with id it works

fallen grove
#

Yeah, I ran into that issue as well, but I fixed it.

#

wait a sec

#

It works better if you add the event to the div tag instead a

#

but this is how you'd do it if you added the event listener to the anchor tag

normal venture
#

tysm it works now

#

and if i do it to the div tag it's the same?

fallen grove
#

You have to change the code a bit

normal venture
#

i've done the same here but i have a white part on the left

normal venture
normal venture
#

i still couldn't fix :(

glass inlet
#

Okay, lets start from the... start :)

First, when you want to style multiple elements in the same way, you should use classes.
Then you can share this class with every element and style it once in css.

example:

    <div id="cate1" class="cate"></div>
    <div id="cate2" class="cate"></div>
    <div id="cate3" class="cate"></div>

you can still have ID's for use on JS, but the styles will be written on the shared class "cate".

css:

.cate {
    border: 3px solid black;
}

.cate:hover {
    border: 10px solid black;
}

Now, for second, when you're not talking about specific events such as clicks or keys, you can just use CSS! :)

using the class selector " .name_of_your_class ", you can set the values when the mouse is not over the element, it counts as its default style.
And when you want hover events, you can use the pseudo-selector ":hover" after the class selector.
For example:
.cate:hover { your style here; }

#

But if you still want to use JS to watch these events you can do as such:

I. Give all of the affected elements a class.
II. Grab all of them with the "querySelectorAll()" built-in function

const elements = document.querySelectorAll(".cate")

III. Loop over all elements using "forEach" or a simple for-loop if you prefer this way:

    elements.forEach(element => {
          
        //your code goes here

    })

In this case, inside the forEach() you'll always have a parameter by default. You can call this guy any name you want, in this case I've choose to call it "element".
This element is the equivalent of

elements[i]

inside a for-loop. Each time it loops, the "element" will be the next one on the list.

IV. create the functions that receive your current "element" being looked:

function categoryOver(element) {
    element.addEventListener("mouseover",                  function() {
        element.style.border = "10px solid black"
        }
    )
}

function categoryOut(element) {
    element.addEventListener("mouseout",              function() {
        element.style.border = "3px solid black"
    }
   )
}

V. apply everything you want to every "element" inside the forEach.

    elements.forEach(element => {
        
        categoryOver(element)
        categoryOut(element)

    })
glass inlet
#

And, about the css spacing problem, you really should try another approach. Flexbox is a good way to solve this.
A more easy solution would be to refactor all your css. You have a lot going on, and the "not using classes" really cripples your debugging.
Try following the tutorial above, with a new clean code :) (and using classes).
Then take a look at flexbox here:
https://www.w3schools.com/css/css3_flexbox_container.asp

#

and, not trying to overwhelm you, but you can use the pseudo-selector on css ":last-child" to make only the last element to not have the right border.

#

Here a simple example.

#

Result:

#

HTML:

#
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="./s.css">
</head>
<body>

<nav>
    <a class="nav-option" href="#">
        <p>My Option!</p>
    </a>
    <a class="nav-option" href="#">
        <p>My Option!</p>
    </a>
    <a class="nav-option" href="#">
        <p>My Option!</p>
    </a>
    <a class="nav-option" href="#">
        <p>My Option!</p>
    </a>
</nav>
    
</body>
</html>
#

CSS:

#
* {
    /* makes your buttons stopping deforming your layout when you hover them in your original example */
    box-sizing: border-box;
}

body {
    font-family: Helvetica;
    /* sets the default font size to be responsive by 1 viewport width */
    font-size: 1vw;
    margin: 0;
}

nav {
    /* sets the nav behavior to flexbox */
    display: flex;
    /* makes children go down if not enough space */
    flex-wrap: wrap;
    /* align the children to be in the vertical center */
    align-items: center;
    /* align them to always start at the beggining */
    justify-content: flex-start;
    /* your beloved solid black border */
    border: 1px solid black;
}

.nav-option {
    /* sets the font size of this particular nav to be half of the above set size */
    font-size: .5rem;
    /* makes some padding on left and right */
    padding: 0 2rem;
    /* sets the text color to black */
    color: black;
    /* takes out the link style */
    text-decoration: none;
    /* again the border */
    border-right: 1px solid black;
}

.nav-option:hover {
    /* makes the background red when hovering */
    background-color: red;
}

.nav-option:last-child {
    /* makes the last child to not have the | at the right */
    border-right: none;
}
#

Hope that helps :)

#

And if you got confused with the JS above, copy & paste the following in your editor:

//selecting all elements
const elements = document.querySelectorAll(".cate")

// creating the function to add a listener to the 
// element when you "mouseover" it.
function categoryOver(element) {
    element.addEventListener("mouseover", function() {
        //applies the style when triggered
        element.style.border = "10px solid black"
    })
}

// creating the function to add a listener to the 
// element when you "mouseout" it.
function categoryOut(element) {
    element.addEventListener("mouseout", function() {
        //applies the style when triggered
        element.style.border = "3px solid black"
    })
}

// looping over all elements, and calling the
// functions above for each one.
elements.forEach(element => {
    // the "element" is equivalent to "elements[i]" in the loop below:
    /*
        for(var i = 0; i < elements.length; i++){
            categoryOver(elements[i])
            categoryOut(elements[i])
        } 
    */
    categoryOver(element)
    categoryOut(element)
})
#

I really recommend you to copy and paste it all in VSCode so you can have nice highlights :)

normal venture
#

also the comments helped a lot understanding the code

glass inlet
#

Thats really cool.
Im happy for you!
Any questions feel free to text me here* :) (forgot about the DM rules)

normal venture
normal venture
#

i learned so many new things

glass inlet
#

Parth, to write a question you can click on "coding help" then "make a new post" (or something)

#

:)