我正在尝试在灵活的孩子中绘制一个占用剩余空间的地图。
我在主要内容的顶部有几个标题,其中一个横幅有时会被隐藏/删除,所以我使用的是flexbox,这样标题就可以消失,而不会影响其他元素的位置。 I.E当我使用绝对位置时,这不起作用。
我的问题是,在Flexbox计算了地图div的高度之前,传单似乎正在计算地图视口。
示例:
这是一张传单的截图,认为地图的高度应该小于应有的值。
如果我检查元素高度是否正确。此外,如果我将计时器放入并强制使用传单使地图大小无效,则地图将重新渲染到正确的高度。
HTML:
<body>
<div class="header">
Header
</div>
<div class="banner">
Banner
</div>
<main class="main">
<div class="nav">
<strong>Navigation</strong>
</div>
<div id="map" class="map-content"></div>
</main>
<script src="script.js"></script>
</body>
CSS:
html, body {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
}
.header {
height: 50px;
background-color: grey;
color: white;
}
.banner {
height: 50px;
background-color: lightgrey;
color: white;
}
.main {
display: flex;
flex: 1 1 auto;
flex-direction: row;
}
.map-content {
flex: 1 1 auto;
}
.nav {
background-color: #2A3D4A;
color: white;
width: 200px;
}
修改
我已经把这个问题复制了一下,万岁!但是我仍然不知道究竟发生了什么。只有在我的应用程序中包含ngAnimate时才会出现此问题。如果我使用ngAnimate,无关紧要。
这是被打破的插件。在初始页面加载时,地图很好。单击about链接,然后返回到地图。请注意,返回时,只有大约一半的地图加载。我将高度记录到控制台。当您离开地图并返回时,它总是大约一半大小。
角度动画是做什么来使元素在一瞬间变成一半大小?这是角度的错误吗?
答案 0 :(得分:5)
看起来传单地图在创建时获得高度,然后如果高度发生变化则需要调用.invalidateSize()
。在传单文档中,它指出Make sure the map container has a defined height, for example by setting it in CSS
(参见http://leafletjs.com/examples/quick-start.html)。由于您没有明确设置高度,而是使用css规则position: absolute; top:0; bottom: 0; left: 0; right: 0;
,因此它有点狡猾。
我认为问题在于,当你加入ngAnimate
时,它会对具有transition
属性的元素产生影响,并且不知何时正确的高度不会被传单及时看到。我想你需要使用一种解决方法,例如检测身高变化并致电.invalidateSize()
尝试将此添加到您的指令:
link: function(scope, element) {
scope.$watch(function() { return element.parent().height(); }, function (val) {
console.log('height changed to: ' + val);
scope.map.invalidateSize();
});
},
scope: true,
使控制器设置为$scope.map = L.map('map',{crs: L.CRS.EPSG4326}).setView([0,0], 4);
,以便传单地图对象位于范围内,并删除.map-content
上的css规则
答案 1 :(得分:2)
我有类似的问题。发生的事情是,当指令加载时,后链接函数计算div元素的clientHeight。 div用flex填充剩余的空间。但它总是有些偏差。在从Web服务器检索到所有模板部分之前,我将其跟踪到角度调用post链接。另一个指令仍在等待其urlTemplate,一旦它进入,该指令导致另一个div改变高度。
如果我只是暂停了足够的时间,那就解决了这个问题。此外,如果我在晚期div中广播一个事件并在计算高度之前等待它,这也可以解决问题。
我找不到一个简单的方法来判断何时加载了所有模板,并且所有指令都完成了操作DOM的操作。指令优先权绝对没有改变事物的顺序。
查看浏览器中的事件序列,看看它是否不是一个迟到的部分模板,足以甩掉时间,以便在你要求执行计算时不会完全执行计算。
答案 2 :(得分:1)
Edited plunkr:http://plnkr.co/edit/pIg9HKwkl0Bfhk4N3wQX?p=preview
尝试&#34; invalide&#34;像这样的地图:
app.directive('leaflet', ['$document','$timeout', function($document,$timeout) {
function controller() {
console.log('in leaflet directive controller');
var element = $document.find('#map');
console.log('main container height: ' + element[0].offsetHeight);
var map = L.map('map',{crs: L.CRS.EPSG4326}).setView([0,0], 4);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
// the timeout wait the view to render
$timeout(function () {
// this rebuild the map
map.invalidateSize();
}, 0);
}
return {
template: '<div id="map" class="map-content"></div>',
controller: controller,
replace: true
}
}]);