0

I'm really poor in JS development, and I try to optimize some code. I am following an online formationt. So sorry to maybe ask a stupid question.

I have this code to optimize:

function border(){

var elmnt = document.getElementsByClassName("menu__item--link")[0];

var elmnt1 = document.getElementsByClassName("menu__item--link")[1];

var elmnt2 = document.getElementsByClassName("menu__item--link")[2];


document.getElementsByClassName("menu__item--border")[0].style.height = 'calc(' + elmnt.offsetHeight + "px" +' + 6px)';
document.getElementsByClassName("menu__item--border")[0].style.marginTop = 'calc( -'+ elmnt.offsetHeight + "px" +' - 15px)';

document.getElementsByClassName("menu__item--border")[1].style.height = 'calc(' + elmnt1.offsetHeight + "px" +' + 6px)';
document.getElementsByClassName("menu__item--border")[1].style.marginTop = 'calc( -'+ elmnt1.offsetHeight + "px" +' - 15px)';

document.getElementsByClassName("menu__item--border")[2].style.height = 'calc(' + elmnt2.offsetHeight + "px" +' + 6px)';
document.getElementsByClassName("menu__item--border")[2].style.marginTop = 'calc( -'+ elmnt2.offsetHeight + "px" +' - 15px)';

}

Is there a way not have to repeat for each elements of my class? This code works for me but I try to do the best code possible.

James Z
  • 12,209
  • 10
  • 24
  • 44
asphel-50
  • 3
  • 1
  • Please check out: [Under what circumstances may I add "urgent" or other similar phrases to my question, in order to obtain faster answers?](https://meta.stackoverflow.com/q/326569) – CertainPerformance Apr 15 '20 at 09:48
  • try this https://stackoverflow.com/questions/15843581/how-to-correctly-iterate-through-getelementsbyclassname – Michael Nelles Apr 15 '20 at 11:02

1 Answers1

1

You can destructure the whole collection into the first, second, and third items:

const [el1, el2, el3] = document.getElementsByClassName("menu__item--link");

But it'd be more DRY to use a loop instead. Save one of the collections in a variable, then iterate over the other collection, and check the index to get the linked element:

const links = document.getElementsByClassName("menu__item--link")
document.querySelectorAll(".menu__item--border").forEach((border, i) => {
  border.style.height = 'calc(' + links[i].offsetHeight + "px" +' + 6px)'
  border.style.marginTop = 'calc( -'+ links[i].offsetHeight + "px" +' - 15px)';
});

If you have more than 3 elements and only need to operate on the first 3, then slice the collection first:

[...document.querySelectorAll(".menu__item--border")]
  .slice(0, 3)
  .forEach((border, i) => {
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320