随着这个问题的发展,正确的标题应该是:页面加载时体宽的差异。。它还与在页面中调整大小的图片有关。如果我们删除图片,差异就会消失。
请注意,这个问题不需要实用的解决方案(我可以用setTimeout()延迟脚本执行,问题就解决了)。我在问,因为我想了解这种行为的技术方面。
在这里写一个答案的脚本时,在SO上,我发现如果在页面加载时或以后计算出元素高度的奇怪差异。
以下是片段:
document.initPictures = function() {
$('.resizeMe').css({
'height': $('#theContainer .col-sm-6').eq(1).height() + 6,
'display': 'flex',
'flex-direction': 'column',
'transition': 'height .4s cubic-bezier(0.55, 0, 0.55, 0.2)'
});
$('.resizeMe img').each(function() {
var src = $(this).attr('src');
$('.resizeMe').append('<div style="flex-basis: 50%; background-image: url(' + src + '); background-size:cover; background-position: center center"' + '</div>');
$(this).remove();
})
};
document.resizePictures = function() {
if ($('#theContainer').outerWidth() > 768) {
$('.resizeMe').css({
'height': $('#theContainer .col-sm-6').eq(1).height()
});
} else {
$('.resizeMe').css({
'height': $('.resizeMe').outerWidth()
});
}
};
$(window).resize(function() {
document.resizePictures();
});
document.initPictures();
&#13;
.main-img {
width: 100%;
height: auto
}
#theContainer {
margin-top: 15px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<div class="row-fluid" id="theContainer">
<div class="col-sm-6 resizeMe">
<img class="filler" src="http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image1.jpg" />
<img class="filler" src="http://www.keenthemes.com/preview/metronic/theme/assets/global/plugins/jcrop/demos/demo_files/image2.jpg" />
</div>
<div class="col-sm-6">
<img class="main-img" src="http://joombig.com/demo-extensions1/images/gallery_slider/Swan_large.jpg" />
</div>
&#13;
您会注意到我在第一个div中将图像制作成第二个div中图像高度的50%(这是要求)。在页面加载时,第二个div的图像高度很短6px
$('#theContainer .col-sm-6').eq(1).height()
,我必须在initPictures()
函数中进行补偿,但resizePictures()
函数中没有必要补偿1}},发生在$(window).resize()
上。
我使用的是最新版本的Chrome,但我也在最新的FF中对其进行了测试。同样的行为。
我很高兴能够理解这种差异是什么。它从何而来?是否与使用jQuery的Bootstrap有关?或者用什么?
注意:测试时,我还尝试使用innerheight()
和outerHeight()
希望我可以绕过&#34;错误&#34;。那时他们都是6px
短。
另一个注意事项:出于测试目的,我为此做了jsFiddle。当我正常加载它时,作为一个小提琴,它有相同的bug并且补偿是必要的。在full screen mode中查看时,不再需要补偿,实际上由于补偿,左列6px
会缩短。
更新:经过使用AvArt记录此操作的一些全面测试后,它全部从body
的宽度开始。默认情况下,没有特殊原因,页面加载时它不是100vw
。
如果在(768 - 17)px
以上的视口宽度下加载,您可以结帐this fiddle。出于某种原因,你们中的一些人从来没有经历过这个&#34; bug&#34;,但是我假设有人做了,因为这个问题已被投票了。
但是,如果你取消注释最后一行CSS,bug就会消失。
因此,如果在页面加载时身体在短时间内具有不同的宽度,.col-sm-6
的宽度会受到影响,从而影响所包含图像的auto
高度,从而影响列高。 6px
差异(有时是7)来自图像&#39;特定的高宽比,但身体宽度的起始差异为17px。
现在,问题仍然存在:为什么body
元素在页面加载时的宽度与100vw
的宽度差异为17px,这应该是默认值,宽度大于(768) - 17)PX
有趣的是 与图片有关,因为如果我们从HTML
删除图片,差异就会消失!
是否有人熟悉浏览器的工作原理以及最初如何应用CSS来解释这种行为?
对于冗长的解释感到抱歉,它只是我几天都无法理解的东西,所以我只需要询问并找出答案。
更新了jsFiddle here。
答案 0 :(得分:4)
问题是Javascript执行顺序。在检查体宽之前必须执行initPictures()
。 Fiddle
答案 1 :(得分:3)
您看到的17px
差异是滚动条宽度。
文档的宽度未知,直到所有资源都已完全加载,因此它为可能的滚动条保留了一些空间。实际上,这意味着window.onLoad
仅在加载所有图像时执行。虽然jQuery的ready
事件会在加载DOM后立即触发。
我创建了一个新的小提琴(http://jsfiddle.net/u7zgz25u/3/)来演示这种行为。 (要清除缓存中的图像,只需更改其网址中的1种颜色)。
在查看http://jsfiddle.net/o1g5x5m6/20/(您的示例没有图片)时,ready
和window.onLoad
事件在(几乎)同时执行,然后才进行实际渲染,因此页面尺寸为浏览器所知。
PS:
我发现一个有趣的小提琴演示了浏览器渲染时考虑的滚动条宽度,尽管有足够大的padding-right
可用:http://jsfiddle.net/9pAcp/2/
某些浏览器实现了渲染延迟(例如Firefox documentation),因此加载了图像后初始宽度和宽度之间的差异。如果在初始渲染延迟之前加载图像,或者没有图像,则浏览器可以计算正确的高度,但是,如果图像尚未加载,并且它们没有已知尺寸,则浏览器需要等待图像加载之前它可以计算它们的大小。因此,估计的文档大小(为滚动条保留的空间)与window.onLoad
之后的实际文档大小之间可能存在差异。
有关在HTML中为图像定义固定高度时会发生什么情况的演示,请参阅http://jsfiddle.net/u7zgz25u/4/。 17px的差异不再存在。
答案 2 :(得分:0)
我没有这个案例的确认来源,但正如我可以看到做一些实验,Flex框有渲染问题。
用具有div的div替换具有真实高度的2个图像 图像作为背景,所以它失去了它的高度。
弹性容器 重新计算这两个图像div的高度,但有一些渲染 问题可能是由于滚动条需要占用一些空间的事实(如在评论上写的那样)。
jQuery在不使用滚动条
$(window).width()
的情况下计算宽度,而使用javascript的window.innerWidth
本机可以看到视口的有效宽度,这比jquery宽度多17倍。对于某些渲染原因,jquery的高度是使用可见的滚动条计算的,如下面的示例中所示,我用
overflow:scroll
替换了主体宽度。
我在不使用弹性框的情况下完成了与此编辑类似的工作:
$('.resizeMe,.cover-img').css({
'height': $('#theContainer .col-sm-6').eq(1).height(),
'transition': 'height .4s cubic-bezier(0.55, 0, 0.55, 0.2)'
});
$('.resizeMe img').each(function() {
var src = $(this).attr('src');
$('.resizeMe').append('<div class="cover-img" style="background-image: url(' + src + '); height: '+$(this).height()+'px;"' + '</div>');
$(this).remove();
});
使用具有高度的div,效果相同但没有近似问题。
jsfiddle有可能的解决方案。
另一个没有渲染问题的例子,留下img标签而不用div替换它们而不用js计算高度: