【发布时间】:2009-12-03 16:30:05
【问题描述】:
我目前正在扩展lavalamp plugin 以处理下拉菜单,但我遇到了一个小问题。我需要知道隐藏元素的offsetWidth。现在显然这个问题没有意义,而我正在寻找的是元素的offsetWidth,如果它没有隐藏的话。
解决方案是显示它,抓住宽度,然后再次隐藏?一定有更好的办法……
【问题讨论】:
标签: javascript jquery css
我目前正在扩展lavalamp plugin 以处理下拉菜单,但我遇到了一个小问题。我需要知道隐藏元素的offsetWidth。现在显然这个问题没有意义,而我正在寻找的是元素的offsetWidth,如果它没有隐藏的话。
解决方案是显示它,抓住宽度,然后再次隐藏?一定有更好的办法……
【问题讨论】:
标签: javascript jquery css
具有 CSS visibility: hidden 的元素的宽度是可测量的。只有当它是 display: none 时,它才不会被渲染。因此,如果确定元素将被绝对定位(因此它们在显示时不会导致布局更改),只需使用css('visibility', 'hidden') 来隐藏您的元素而不是hide(),您应该可以测量宽度。
否则,是的,show-measure-hide 确实有效。
【讨论】:
我唯一能想到的就是显示它(或它的克隆)以允许检索 offsetWidth。
对于此测量步骤,只需将其位置设为绝对值,并将其 x 或 y 值设为大负数,这样它就会呈现但对用户不可见。
【讨论】:
您可以使用以下函数来获取隐藏容器内的元素的外部宽度。
$.fn.getHiddenOffsetWidth = function () {
// save a reference to a cloned element that can be measured
var $hiddenElement = $(this).clone().appendTo('body');
// calculate the width of the clone
var width = $hiddenElement.outerWidth();
// remove the clone from the DOM
$hiddenElement.remove();
return width;
};
您可以根据自己的情况将.outerWidth() 更改为.offsetWidth()。
该函数首先克隆元素,将其复制到可见的地方。然后它检索偏移宽度并最终删除克隆。下面的 sn-p 说明了这个函数将是完美的情况:
<style>
.container-inner {
display: none;
}
.measure-me {
width: 120px;
}
</style>
<div class="container-outer">
<div class="container-inner">
<div class="measure-me"></div>
</div>
</div>
请注意,如果对元素应用了 CSS 来改变元素的宽度,而如果它是 body 的直接后代则不会应用,那么此方法将不起作用。所以这样的事情将意味着该功能不起作用:
.container-outer .measure-me {
width: 100px;
}
您需要:
.measure-me { width: 100px; }
appendTo() 以将克隆添加到您的CSS 也将应用于克隆的位置。确保无论你把它放在哪里,该元素都是可见的:.appendTo('.container-outer')
同样,这个函数假设元素是隐藏的,因为它在一个隐藏的容器中。如果元素本身是display:none,您可以简单地添加一些代码以使克隆可见,然后再检索它的偏移宽度。像这样的:
$.fn.getHiddenOffsetWidth = function () {
var hiddenElement $(this)
width = 0;
// make the element measurable
hiddenElement.show();
// calculate the width of the element
width = hiddenElement.outerWidth();
// hide the element again
hiddenElement.hide();
return width;
}
这适用于这样的情况:
<style>
.measure-me {
display: none;
width: 120px;
}
</style>
<div class="container">
<div class="measure-me"></div>
</div>
【讨论】:
两种选择:
left:-10000px)visibility: hidden 或opacity: 0 而不是hide()。无论哪种方式都可以隐藏元素,但仍然可以获得计算出的宽度。在 thi 上使用 Safari 时要小心,它非常快,有时甚至太快...
【讨论】:
用法:
console.log('width without actual: ' + $('#hidden').width());
console.log('width with actual: ' + $('#hidden').actual('width'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.actual/1.0.19/jquery.actual.min.js"></script>
<div style="width: 100px; display: none;">
<div id="hidden"></div>
</div>
【讨论】:
如果您知道元素是父元素的全宽,另一种方法是创建递归方法:
es5:
var getWidth;
getWidth = function($el){
return $el.offsetWidth || getWidth($el.parentElement);
}
var width = getWidth(document.getElementById('the-element'));
es6:
let getWidth
getWidth = ($el) => $el.offsetWidth || getWidth($el.parentElement)
const width = getWidth(document.getElementById('the-element'))
【讨论】:
我所做的是; 在隐藏该元素时,将其宽度存储在其数据集中。 只有当您可以通过编程方式隐藏时,它才会对您有用。
即。
隐藏时;
var elem = $("selectorOfElement");
elem.dataset.orgWidth = elem.clientWidth;
以后获取时;
var elem = $("selectorOfElement");
var originalWidthWas = elem.dataset.orgWidth;
【讨论】:
那是因为它通过 display: none;我过去所做的是制作一个“接收器” div,我使用绝对定位将其从页面上移开。然后我将新元素加载到其中,抓取尺寸,然后在我完成后将其移除 - 然后在我完成后移除接收器。
您可以做的另一件事是不使用 hide();但改为设置可见性:隐藏;展示: ;然而,这意味着无论节点连接到哪里都会呈现空白区域。
【讨论】:
var $hiddenElement = $('#id_of_your_item').clone().css({ left: -10000, top: -10000, position: 'absolute', display: 'inline', visibility: 'visible' }).appendTo('body');
var width = parseInt($hiddenElement.outerWidth());
$hiddenElement.remove();
【讨论】:
我试图找到隐藏元素的工作函数,但我意识到 CSS 比大家想象的要复杂得多。 CSS3 中有许多新的布局技术可能不适用于所有以前的答案,例如灵活的框、网格、列甚至复杂父元素内的元素。
flexibox 示例
我认为唯一可持续且简单的解决方案是实时渲染。那时,浏览器应该为您提供正确的元素大小。
遗憾的是,JavaScript 没有提供任何直接事件来通知元素何时显示或隐藏。但是,我创建了一些基于 DOM Attribute Modified API 的函数,当元素的可见性发生变化时将执行回调函数。
$('[selector]').onVisibleChanged(function(e, isVisible)
{
var realWidth = $('[selector]').width();
var realHeight = $('[selector]').height();
// render or adjust something
});
更多信息,请访问我的项目 GitHub。
【讨论】:
抱歉,这次谈话我迟到了。我很惊讶没有人提到getComputedStyle。 (请注意,这仅在 CSS 设置宽度值时才有效)
抢元素:let yourEle = document.getElementById('this-ele-id');
并使用函数:getComputedStyle(yourEle).width
这将返回一个字符串,因此您必须从字符串中删除数字。
即使元素的显示样式设置为none,这也有效。
其他要阅读的文章包括zellwk.com
【讨论】: