使用JavaScript均衡元素高度

Equalizing Element Heights with JavaScript

本文关键字:元素 高度 JavaScript 使用      更新时间:2023-09-26

我正在编写Javascript,它将使用类为" equlizm "的元素,获得所有。children的。offsetheight,确定最大值,然后将所有。children的高度设置为该值。

我的问题是,虽然我可以让它回显值,但它只为第一个子元素设置它们。

我在CodePen上设置了代码。但这里是脚本,完成我的诊断控制台。日志:

var eqlizmContainers = document.querySelectorAll(".eqlizm");
function getArrMax(numArray) {
    return Math.max.apply(null, numArray);
}
function findMaxHeight(targetContainer) {
    var eqlizNodes = targetContainer.children;
    var childHeights = [];
    for (c = 0; c < eqlizNodes.length; c++) {
        childHeights.push(eqlizNodes[c].offsetHeight);
    }
    return getArrMax(childHeights);
}
function eqlizHeight(targetContainer) {
    var eqlizNodes = targetContainer.children;
    //console.log(eqlizNodes);
    for (c = 0; c < eqlizNodes.length; c++) {
        //console.log(targetContainer + " " + c);
        //console.log(eqlizNodes[c]);
        eqlizNodes[c].style.height = findMaxHeight(targetContainer) + "px";
    }
}
for (i = 0; i < eqlizmContainers.length; i++) {
    //console.log("Tier " + (i+1) + ": " + findMaxHeight(eqlizmContainers[i]) + "px");
    eqlizHeight(eqlizmContainers[i]);
}

让这个函数工作后,我将添加事件侦听器来调整浏览器窗口的大小。

我已经四处寻找解决方案,但我能找到的所有解决方案都涉及jQuery,我不想使用它

你发布的代码最大的问题是你误解了JavaScript中的变量作用域。

所有变量都是函数作用域的,不管它们在哪个块中初始化。

您的c = 0在全局作用域中被保存。
window.c; //0因此,在eqlizHeight内部,您将c设置为0,然后对于每次调用findMaxHeight(这看起来像一个相当大的de-op,它更适合在循环外运行,并且每个父节点存储一次),您将运行c的值,直到第一个父节点的子节点的长度。

快速而肮脏的解决方案是将var c = 0;添加到函数中的变量声明中。

那么你的for结构可以看起来像for (; c < ...; c++)

我更喜欢以函数方式工作,没有显式循环,所以我快速运行了第二个解决方案:

// turns an array-like into an array (el.children, document.querySelectorAll(...), etc)
function slice (arrlike, start, end) {
  return [].slice.call(arrlike, start, end);
}
// takes a property name and returns a reusable function
// var getName = pluck("name");
// getName({ name: "Bob" }); // Bob
// [{ name: "Bob" }, { name: "Doug" }].map(getName); // ["Bob", "Doug"]
function pluck (key) {
  // returns a function, which will pull the same property from any object it gets
  return function (obj) { return obj[key]; };
}
// it's just faster calling query(selector); than document.querySelector(selector);
function query (selector) {
  return document.querySelector(selector);
}
// same as above, but I also turn the resulting HTMLCollection into an Array
function queryAll (selector) {
  return slice(document.querySelectorAll(selector));
}
// take an array of numbers and return the max
function max (numbers) {
  numbers = Array.isArray(numbers) ? numbers : slice(arguments);
  return Math.max.apply(Math, numbers);
}
// take an array of numbers and return the min
function min (numbers) {
  numbers = Array.isArray(numbers) ? numbers : slice(arguments);
  return Math.min.apply(Math, numbers);
}
// returns an object with top, right, bottom, left, width, height in pixels
// (measured from the visible part of the page, so scrolling affects the numbers)
function getBoundingClientRect (el) {
  return el.getBoundingClientRect();
}
// takes a style-name, and value, and returns a reusable function
// var setHeightTo100 = setStyle("height", "100px");
// setHeightTo100(el_1);
// setHeightTo100(el_2);
function setStyle (key, value) {
  // sets the same el.style[key] = value; for every element it's passed
  return function (el) { el.style[key] = value; };
}
// takes an array of elements
function resizeChildren (nodes) {
  nodes = Array.isArray(nodes) ? nodes : slice(arguments);
  // for each element ("container")
  nodes.forEach(function (container) {
    // get the container's children as an array
    var children = slice(container.children);
    // get the max( ) of the .height properties of the boundingClientRects of the children
    var maxHeight = max(children.map(getBoundingClientRect).map(pluck("height")));
    // set style.height = maxHeight + "px" on each child
    children.forEach(setStyle("height", maxHeight + "px"));
  });
}
// for a list of all ".eqlizm" children, resizeChildren
resizeChildren(queryAll(".eqlizm"));

如果你把它粘贴到你的笔里,我想你会发现它很好。

编辑:说明快速&对先前存在的代码的脏修复

var eqlizmContainers = document.querySelectorAll(".eqlizm");
var i = 0;
function getArrMax(numArray) {
    return Math.max.apply(null, numArray);
}
function findMaxHeight(targetContainer) {
    var eqlizNodes = targetContainer.children;
    var childHeights = [];
    var c = 0;
    for (c = 0; c < eqlizNodes.length; c++) {
        childHeights.push(eqlizNodes[c].offsetHeight);
    }
    return getArrMax(childHeights);
}
function eqlizHeight(targetContainer) {
    var eqlizNodes = targetContainer.children;
    var c = 0;
    for (c = 0; c < eqlizNodes.length; c++) {
        eqlizNodes[c].style.height = findMaxHeight(targetContainer) + "px";
    }
}
for (i = 0; i < eqlizmContainers.length; i++) {
    eqlizHeight(eqlizmContainers[i]);
}

除了删除注释,我所做的只是添加了两个var c;行。是否将var c初始化为一个值并不重要;重要的是你使用var来宣布它。否则,它将被保存在全局作用域中。

当然,您可以继续使用a, b, d, e, f, g, h, j, ...,但这意味着任何时候同一页面上的两段代码使用x,其中一段将覆盖另一段…

函数内部的

var c;告诉JavaScript c的家在那里,不要再往下看

为它们指定一个相似的类,并循环遍历它们。

$(document).ready(function(){
    var height = 0;
    $(".homepage-product").each(function(){
        if ($(this).height() > height){
            height = $(this).height()
        }
    });
    $(".homepage-product").each(function(){
        $(this).height(height);
    });
});

JSFIDDLE示例