Jam*_*les 24 html javascript css yui
我需要测量隐藏元素内部div的offsetHeight.
<div id="parent" style="display: none;">
<div id="child">Lorem Ipsum dolor sit amet.</div>
</div>
Run Code Online (Sandbox Code Playgroud)
父div 必须设置为" display:none".我无法控制.我意识到子div的offsetHeight将为0.我需要找到一个解决方法.
我玩过的东西是当页面加载时,我复制父节点的子节点,在设置为" visiblity:hidden" 的页面上注入div .然后我测量这些元素的高度,并在完成后删除节点.
还有其他想法吗?
更新: 我最不得不做的是:
使用YUI 2,在页面加载时,我发现给定类名的所有元素都设置为display:none,或者其高度和宽度为0(这是测量元素是否存在或者父元素是否设置为显示的一种方式:没有).然后我将该元素设置为display:block.然后,我检查了它的父母同样的事情,并向父母展示,直到找到一个可见的父母.一旦最高显示:没有祖先设置为显示:块,我可以测量我的元素.
测量完所有元素后,我将所有元素重置为display:none.
kan*_*gax 22
当你获得元素的尺寸时,你需要让元素的父元素在非常短的时间内可见.在通用解决方案中,通常遍历所有祖先并使其可见.然后将它们的display值设置回原始值.
当然存在性能问题.
我们认为在执行的Prototype.js这种做法,但结束了getWidth和getHeight 制造只有实际的元素可见,而无需遍历祖先.
替代解决方案的问题 - 例如将元素从"隐藏"父元素中取出 - 是某些元素一旦超出其"常规"层次结构就可能不再适用于元素.如果你有这样的结构:
<div class="foo" style="display:none;">
<div class="bar">...</div>
</div>
Run Code Online (Sandbox Code Playgroud)
和这些规则:
.bar { width: 10em; }
.foo .bar { width: 15em; }
Run Code Online (Sandbox Code Playgroud)
然后将元素从其父元素中取出实际上会导致错误的维度.
小智 14
一种解决方法是height将0
.hidden {
height: 0;
overflow: hidden;
}
Run Code Online (Sandbox Code Playgroud)
然后获取元素scrollHeight。
document.querySelector('.hidden').scrollHeight
Run Code Online (Sandbox Code Playgroud)
尽管元素没有出现,但 scrollHeight 将正确地为您提供高度。我也不认为它会影响元素流。
示例:https : //jsfiddle.net/de3vk8p4/7/
参考:https : //developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements#How_big_is_the_content.3F
Not*_*ser 13
如果使用style.display = "none",元素将具有0宽度和高度,
但使用style.visibility = "hidden"相反,元素将具有浏览器计算的宽度和高度(通常).
Cla*_*diu 11
制作一个没有Jquery的纯js解决方案,没有克隆(我想更快)
var getHeight = function(el) {
var el_style = window.getComputedStyle(el),
el_display = el_style.display,
el_position = el_style.position,
el_visibility = el_style.visibility,
el_max_height = el_style.maxHeight.replace('px', '').replace('%', ''),
wanted_height = 0;
// if its not hidden we just return normal height
if(el_display !== 'none' && el_max_height !== '0') {
return el.offsetHeight;
}
// the element is hidden so:
// making the el block so we can meassure its height but still be hidden
el.style.position = 'absolute';
el.style.visibility = 'hidden';
el.style.display = 'block';
wanted_height = el.offsetHeight;
// reverting to the original values
el.style.display = el_display;
el.style.position = el_position;
el.style.visibility = el_visibility;
return wanted_height;
}
Run Code Online (Sandbox Code Playgroud)
这是演示 https://jsfiddle.net/xuumzf9k/1/
如果你能找到任何改进,请告诉我(因为我在我的主要项目中使用它)
一个辅助函数——
/**
* Get an element's computed style, optionally locking width/height.
* @param el Element to measure
* @param lockWidth Lock width to current width to measure height
* @param lockHeight Lock height to current height to measure width
* @returns Element's DOMRect
*/
export const getElementRect = (el: HTMLElement, lockWidth = true, lockHeight = false): DOMRect => {
const clone = el.cloneNode(true) as HTMLElement;
clone.style.cssText = 'position:fixed;top:0;left:0;overflow:auto;visibility:hidden;pointer-events:none;width:unset;min-width:unset;max-width:unset;height:unset;min-height:unset;max-height:unset;'
if (lockWidth || lockHeight) {
const { width, height } = el.getBoundingClientRect();
if (lockWidth) clone.style.cssText += `width:${ width }px;`;
if (lockHeight) clone.style.cssText += `height:${ height }px;`;
}
document.body.append(clone);
const rect = clone.getBoundingClientRect();
clone.remove();
return rect;
};
Run Code Online (Sandbox Code Playgroud)
默认情况下 - 将锁定宽度以在此宽度测量高度。大多数用例需要测量其栖息地中的元素的高度偏移,因此这可以确保测量准确。
一个具有“类似手风琴”的动画打开/关闭的示例,允许动态高度。
/**
* Get an element's computed style, optionally locking width/height.
* @param el Element to measure
* @param lockWidth Lock width to current width to measure height
* @param lockHeight Lock height to current height to measure width
* @returns Element's DOMRect
*/
export const getElementRect = (el: HTMLElement, lockWidth = true, lockHeight = false): DOMRect => {
const clone = el.cloneNode(true) as HTMLElement;
clone.style.cssText = 'position:fixed;top:0;left:0;overflow:auto;visibility:hidden;pointer-events:none;width:unset;min-width:unset;max-width:unset;height:unset;min-height:unset;max-height:unset;'
if (lockWidth || lockHeight) {
const { width, height } = el.getBoundingClientRect();
if (lockWidth) clone.style.cssText += `width:${ width }px;`;
if (lockHeight) clone.style.cssText += `height:${ height }px;`;
}
document.body.append(clone);
const rect = clone.getBoundingClientRect();
clone.remove();
return rect;
};
Run Code Online (Sandbox Code Playgroud)
function getElementRect(el, lockWidth, lockHeight) {
if (lockWidth === undefined) lockWidth = true;
const clone = el.cloneNode(true);
clone.style.cssText = 'position:fixed;top:0;left:0;overflow:auto;visibility:hidden;pointer-events:none;width:unset;min-width:unset;max-width:unset;height:unset;min-height:unset;max-height:unset;'
if (lockWidth || lockHeight) {
const { width, height } = el.getBoundingClientRect();
if (lockWidth) clone.style.cssText += `width:${ width }px;`;
if (lockHeight) clone.style.cssText += `height:${ height }px;`;
}
document.body.append(clone);
const rect = clone.getBoundingClientRect();
clone.remove();
return rect;
};
var expanded = false;
var timeout;
function toggle() {
var el = document.getElementById('example');
expanded = !expanded;
if (expanded) {
el.style.maxHeight = getElementRect(el).height + 'px';
// Remove max-height setting to allow dynamic height after it's shown
clearTimeout(timeout);
var openTimeout = timeout = setTimeout(function() {
el.style.maxHeight = 'unset';
clearTimeout(openTimeout);
}, 1000); // Match transition
} else {
// Set max height to current height for something to animate from
el.style.maxHeight = getElementRect(el).height + 'px';
// Let DOM element update max-height, then set to 0 for animated close
clearTimeout(timeout);
var closeTimeout = timeout = setTimeout(function() {
el.style.maxHeight = 0;
clearTimeout(closeTimeout);
}, 1);
}
}Run Code Online (Sandbox Code Playgroud)
#example {
overflow: hidden;
max-height: 0;
transition: max-height 1s;
}Run Code Online (Sandbox Code Playgroud)
因此,这里是基于lod3n的答案并借助999的注释的有效jQuery解决方案:
var getHiddenElementHeight = function(element){
var tempId ='tmp-'+ Math.floor(Math.random()* 99999); //生成唯一ID以防万一
$(element).clone()
.css('position','absolute')
.css('height','auto')。css('width','1000px')
//将权利直接注入父元素,以便所有CSS都适用(是的,我知道,除了:first-child和其他伪东西。
.appendTo($(element).parent())
.css('left','-10000em')
.addClass(tempId).show()
h = $('。'+ tempId).height()
$('。'+ tempId).remove()
返回h;
}
请享用!