Javascript 奇怪的行为getBoundingClientRect()和F5/重载,什么';发生什么事了?

Javascript 奇怪的行为getBoundingClientRect()和F5/重载,什么';发生什么事了?,javascript,html,css,Javascript,Html,Css,我为冗长的代码辩解,我一次又一次地剥光衣服。代码笔在本质上是没有用的。我使代码完全独立,您只需将其剪切并粘贴到html文件中即可查看其行为 <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Garden</title&

我为冗长的代码辩解,我一次又一次地剥光衣服。代码笔在本质上是没有用的。我使代码完全独立,您只需将其剪切并粘贴到html文件中即可查看其行为

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>Garden</title>
</head>
<body>
<style>

#page {      
    display: inline-grid;
    grid-template-columns:auto;
    grid-template-rows: 3;
    grid-template-areas: 
    "header"
    "map"
    "footer";
}
  
#header {       
    grid-area: header;
    color: white;
    background-color: grey;
    border: 2px solid grey;
    border-bottom: none;
    border-radius: 10px 10px 0px 0px;   
    padding: 5px;  
}

#map {   
    grid-area: map;
    border: 2px solid grey;
    border-top: none;
    padding: 5px;
}   

#imagewrapper {    
    position: relative;
    border: 1px solid grey;
    padding: none;
    margin: none;
}

#mapimage { 
    display: inline;
    max-width: 100%;
    margin-bottom: -4px;
}

.pin_container {
    
    position: absolute;
    border: 2px solid grey;
    border-radius: 10px 10px 10px 10px;
    cursor: grab;
    padding: 3px;
}

#footer {
    grid-area: footer;
    color: white;
    background-color: grey;
    border: 2px solid grey;
    border-right: none;
    border-radius: 0px 0px 10px 10px;   
    padding: 5px;  
}
</style>
<div id='page'>
    <div id='header'>De Botanische Tuin Kerkrade</div>
    <div id='map' data-id='14'>
        <div id='imagewrapper'>
            <img id='mapimage' src='https://i.ibb.co/cQF07s8/map-g3-v1.png'>
            <div id='b27' class='pin_container' style='left:479px; top:792px;' data-img='map_g3_b27_v0.png'>Hubertus Borders</div>
            <div id='b22' class='pin_container' style='left:385px; top:568px;' data-img='map_g3_b22_v0.png'>De Oude Tuin</div>
            <div id='b9' class='pin_container' style='left:400px; top:400px;' data-img='map_g3_b9_v0.png'>De Thematuin</div>
        </div>
    </div>
    <div id='footer'><span class='nav_current'>De Botanische Tuin Kerkrade</span></div>
</div>

<script type="text/javascript">

    var map  = document.getElementById('imagewrapper').getBoundingClientRect();
    var pins = document.querySelectorAll('.pin_container');
    var pin;
    var div;
    var loc_x;
    var loc_y;

    for ( var i = 0; i < pins.length; i++ ) { 
        
        pin    = pins[i];
        div    = pin.getBoundingClientRect();
     
        console.log( pin.textContent+"("+pin.id+") - imagewrapper.width="+map.width+", pin_container.width="+div.width );
    }
</script>
</body>
</html>
但是,如果我刷新页面,会得到以下结果:

Hubertus Borders(b27) - imagewrapper.width=190.93333435058594, pin_container.width=68.66
De Oude Tuin(b22) - imagewrapper.width=190.93333435058594, pin_container.width=44.64
De Thematuin(b9) - imagewrapper.width=190.93333435058594, pin_container.width=79.31
正如你所看到的,地图和图钉的宽度现在都是胡说八道。 在我将此代码剥离到骨骼之前,如果使用ctrl+f5,我会得到不同的结果。不幸的是,我似乎找不到是什么代码导致了这种行为。 我向Chrome、Firefox标准版和开发者咨询过。这两个狐狸产生了上面描述的行为,Chrome始终给我错误的输出,无论我是用F5还是用新的负载

请注意,无论我使用什么浏览器或操作,结果渲染都是我对正确输出的期望。但是,它会弄乱使用getBoundingClientRect()的居中脚本


这里发生了什么?

问题不在于图像加载太晚,或者至少它间接触发了它

要复制,只需在控制台中再次在提供的代码中运行循环


这与其说是答案,不如说是解释。

我们处理的是绝对定位元素,绝对定位元素没有维度,它们依赖于它们的内容,在这种情况下是文本,文本是不可预测的

当使用这四个属性定位定位的元素时,它将在到达其中一个边时停止移动,并开始收缩而不是移动,直到到达最长单词的限制

这就是这里发生的事情,在图像加载之前,父元素的宽度变小,元素定位在左边缘之外,因此它们收缩并具有一定的宽度值,在图像加载之后,父元素的宽度变大,元素的宽度也随之变化

一个解决方案是定义定位元素的宽度/高度,或者可能是
空白:nowrap


我不确定你的应用程序将如何扩展,因此我无法给出一个永久性的解决方案,定义宽度/高度可能不可取

我无法重现我的问题,但有消息告诉我问题是在图像完全加载之前执行的代码。这也是我的第一个想法,但de image标记没有什么特别之处,图像大小没有那么大,我使用ssd上的所有文件对其进行了本地测试。因此,如果此设置加载图像的速度不足以加载此脚本,那么会发生什么?我理解您的意思,但为什么在我点击F5时会发生这种情况,而在从书签或链接加载页面时不会发生这种情况?我有几乎相同的设置来放置管脚,但是在这种情况下,图像作为背景添加到imagewrapper div中(因为我不需要调整贴图的大小)。当我使用相同的js函数来居中引脚时,看不出有什么问题。似乎使地图可调整大小给了我很多伤害(我不知道,我不能像你那样复制它。所以你的设置有些不同,我假设缓存有问题,但即使禁用缓存也会产生同样的结果。奇怪,奇怪,奇怪。确实是加载导致了问题。我在代码上延迟了1毫秒,然后它工作了,除非我强制刷新缓存。在最后,我简单地将px中地图的宽度添加到图像标记中,解决了所有问题。现在我想知道为什么当视口变得比图像小时,图像仍然会调整大小,但这是另一个问题。感谢您帮助我前进,@Zohir Salak!向代码添加延迟基本上与刷新或每秒运行代码相同此时,您最好等待图像加载,然后运行代码,这可能是一个合适的选择solution@ZohirSalak首先,你说图像加载延迟不是原因,但你说这是因为图像尚未加载,所以父框在加载之前大小不同。它比哪一个大?
Hubertus Borders(b27) - imagewrapper.width=190.93333435058594, pin_container.width=68.66
De Oude Tuin(b22) - imagewrapper.width=190.93333435058594, pin_container.width=44.64
De Thematuin(b9) - imagewrapper.width=190.93333435058594, pin_container.width=79.31