我目前正在扩展lavalamp plugin以处理下拉菜单,但我遇到了一个小问题。我需要知道隐藏元素的offsetWidth
。现在显然这个问题毫无意义,而我正在寻找的是元素的offsetWidth
是不是被隐藏了。
解决方案是显示它,抓住宽度,然后再次隐藏?必须有更好的方法......
答案 0 :(得分:34)
我唯一能想到的是显示它(或它的一个克隆)以允许检索offsetWidth。
对于此测量步骤,只需使其位置绝对且其x或y值为负值,因此它将呈现但不会对用户可见。
答案 1 :(得分:31)
具有CSS visibility: hidden
的元素的宽度是可测量的。只有在它display: none
时它才会被渲染。因此,如果确定元素将被绝对定位(因此它们在显示时不会导致布局更改),只需使用css('visibility', 'hidden')
隐藏元素而不是hide()
,您应该没问题测量宽度。
否则,是的,show-measure-hide确实有用。
答案 2 :(得分:12)
您可以使用以下函数获取隐藏容器中元素的外部宽度。
$.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()
。
该函数首先克隆元素,将其复制到可见的位置。然后它检索偏移宽度,最后删除克隆。以下代码段说明了此功能完美的情况:
<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>
答案 3 :(得分:2)
两个选项:
left:-10000px
)visibility: hidden
或opacity: 0
代替hide()
。无论哪种方式都可以隐藏元素,但仍然能够获得计算出的宽度。在这期间小心Safari,它非常快,有时太快......
答案 4 :(得分:1)
我做的是; 在隐藏该元素时,将其宽度存储在其数据集中。 如果您可以通过编程方式隐藏,它将仅适用于您。
即。
隐藏时;
var elem = $("selectorOfElement");
elem.dataset.orgWidth = elem.clientWidth;
以后获取;
var elem = $("selectorOfElement");
var originalWidthWas = elem.dataset.orgWidth;
答案 5 :(得分:1)
<强>用法:强>
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>
答案 6 :(得分:0)
那是因为它隐藏的via显示:none;我过去所做的就是制作一个“接收器”div,我使用绝对定位将其从页面上移除。然后我将新元素加载到其中,抓取尺寸,然后在完成后将其移除 - 然后在完成后移除接收器。
你可以做的另一件事是不使用hide();但要设置可见性:隐藏;显示:;但是,这意味着将在节点附加的任何位置呈现空白区域。
答案 7 :(得分:0)
我试图找到隐藏元素的工作函数,但我意识到CSS比每个人都想象的要复杂得多。 CSS3中有许多新的布局技术可能不适用于所有先前的答案,如灵活的框,网格,列或复杂父元素内的元素。
flexibox示例
我认为唯一可持续的&amp;简单的解决方案是实时渲染。那时,浏览器应该为您提供正确的元素大小。
可悲的是,JavaScript在显示或隐藏元素时不提供任何直接事件通知。但是,我创建了一些基于DOM Attribute Modified API的函数,当元素的可见性发生变化时,它将执行回调函数。
$('[selector]').onVisibleChanged(function(e, isVisible)
{
var realWidth = $('[selector]').width();
var realHeight = $('[selector]').height();
// render or adjust something
});
有关详细信息,请访问我的项目GitHub。
答案 8 :(得分:0)
如果您知道该元素是父元素的全宽,则另一种方法是创建一个递归方法:
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'))
答案 9 :(得分:0)
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();