使用JavaScript均衡元素高度
Equalizing Element Heights with JavaScript
我正在编写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示例
- 查找元素高度,包括边距
- 根据元素高度和宽度的百分比变化增加或减少字体大小
- 更改第二次推送时不起作用的元素高度
- 指示中的角度手表元素高度
- 在 HTML/CSS 中更改元素高度与宽度的比较
- 获取元素高度的正确方法(使用所有浏览器?)
- 访问NativeScript中的元素高度
- 如何“;“修复”;显示滚动条时的容器元素高度
- 当元素高度不够时,如何强制滚动
- CSS webkit溢出隐藏和HTML元素高度
- 如果元素高度大于 x 添加类“纵向”,则添加类“横向”
- 如何获取离子对话框中动态加载的元素的元素高度
- AngularJS 指令中的元素高度
- 铬:设置元素高度的脚本是什么
- 哇.js偏移等于元素高度
- 如何获得隐藏元素高度
- jQuery - 如果其他元素可见,则更改元素高度
- 根据元素高度拆分段落的最有效方法
- 检测元素高度变化,如果太小则隐藏
- 根据 jQuery 中多个实例上的另一个元素高度设置高度