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>