Home > Enterprise >  javascript: Use reduce() method to determine widest DOM element?
javascript: Use reduce() method to determine widest DOM element?

Time:10-24

I'm trying to use the Javascript reduce() method to find the element with the largest width in a set of DOM nodes:

function get_elementWidth(ELEMENT) {
  const DOMrect = ELEMENT.getBoundingClientRect();
  const width = DOMrect.width;
  return width
}

function get_widestElemet(ELEMENTS) {
  const widestElement = ELEMENTS.reduce((a, b) => Math.max(get_elementWidth(a), get_elementWidth(b)))
  return widestElement;
}

const elements = document.querySelectorAll('.ElementGroup__element');
console.log(get_widestElemet([...elements]))
.ElementGroup {
  display: flex;
  flex-direction: column;
}
<div >
  <span >Short Element</span>
  <span >Short Element</span>
  <span >Looooooooooong Element</span>
</div>

However, this approach throws the error ELEMENT.getBoundingClientRect is not a function (run the snippet check the console). I believe this happens because the final value passed to my get_elementWidth(ELEMENT) function (by the reduce() method) is the actual largest width (so a number and not a DOM node), but I don't know how to solve it.

CodePudding user response:

You don't need to use reduce here, just map get_elementWidth to each ELEMENT and then take Math.max of all the values.

Note you need to use align-items: flex-start on the container div; otherwise the spans all expand to the width of the container.

function get_elementWidth(ELEMENT) {
  const DOMrect = ELEMENT.getBoundingClientRect();
  return DOMrect.width;
}

function get_widestElement(ELEMENTS) {
  const widestElement = Math.max(...ELEMENTS.map(get_elementWidth))
  return widestElement;
}

const elements = document.querySelectorAll('.ElementGroup__element');
console.log(get_widestElement([...elements]))
.ElementGroup {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
<div >
  <span >Short Element</span>
  <span >Short Element</span>
  <span >Looooooooooong Element</span>
</div>

If you want to get the widest element itself, a simple for loop is probably best.

function get_elementWidth(ELEMENT) {
  const DOMrect = ELEMENT.getBoundingClientRect();
  return DOMrect.width;
}

function get_widestElement(ELEMENTS) {
  let maxWidth = -1
  let widestElement
  for (let ELEMENT of ELEMENTS) {
    let width = get_elementWidth(ELEMENT)
    if (width > maxWidth) {
      maxWidth = width
      widestElement = ELEMENT
    }
  }
  return { widestElement, width: maxWidth };
}

const elements = document.querySelectorAll('.ElementGroup__element');
console.log(get_widestElement([...elements]))
.ElementGroup {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
<div >
  <span >Short Element</span>
  <span >Short Element</span>
  <span >Looooooooooong Element</span>
</div>

  • Related