使用JavaScript均衡Element Heights

时间:2015-09-23 14:13:18

标签: javascript html

我正在编写将使用“eqlizm”类的元素的Javascript,获取所有.children的.offsetHeight,确定最大值,然后将所有.children的高度设置为该值。 / p>

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

我在CodePen.io上设置了代码,但这里是脚本,配有我的诊断console.logs:

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,我想避免使用它。

2 个答案:

答案 0 :(得分:0)

您发布的代码的最大问题是您误解了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"));

如果您将其粘贴到笔中,我认为您会发现它的效果很好。

编辑:说明快速&amp;修复预先存在的代码

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,就会覆盖另一段...

函数内部的{p> var c;告诉JavaScript c的主页在那里,而不是向上看。

答案 1 :(得分:-1)

将所有目标分配给一个类似的类并循环遍历它们。

$(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 example