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>
