Display booklet map after flexbox calculates height

I am trying to draw a map in a flex child that takes up the remaining space.

I have a couple of headers on top of the main content, and one of the banners is sometimes hidden / deleted, so I use flexbox so that the header can go away without affecting the position of the other elements. I.E. This does not work when I use absolute positions.

My problem is that the booklet seems to calculate the map viewport before flexbox has calculated the height for the map div.

Example:

Here is a screenshot of the booklet in which the height of the cards is less than it should be.

enter image description here

If I check the height of the elements, this is correct. And, in addition, if I put a timer and made the sheet reject the size of the map, the map will be displayed again at the correct height.

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; } 

EDIT:

I reproduced the problem in the plunger, cheers! However, I still do not know exactly what is happening. The problem occurs when I include ngAnimate in my application. It doesn't matter if I use ngAnimate or not.

Here is a broken plunger. When the page loads, the map is in order. Follow the link, then return to the map. Please note that when returning only about half the load on the card. I record the height on the console. When you move away from the card and return it about half the size.

What is angular animate to make an element be half in size within a second? Is this a bug in angular?

http://plnkr.co/edit/dyBH1Szo3lIEWajKqXWj?p=preview

+5
source share
3 answers

It looks like the booklet map gets height when it is created, and then you need to call .invalidateSize() if the height changes. The flyer docs say Make sure the map container has a defined height, for example by setting it in CSS (see http://leafletjs.com/examples/quick-start.html ). Since you do not set the height explicitly, but instead have the rule css position: absolute; top:0; bottom: 0; left: 0; right: 0; position: absolute; top:0; bottom: 0; left: 0; right: 0; it's a bit dodgy.

I believe the problem is that when you enable ngAnimate , it affects elements with transition attributes, and somehow the correct height is not visible by the sheet in time. I think you will need to use a workaround, for example. height change detection and .invalidateSize() call

Try adding this to your directive:

 link: function(scope, element) { scope.$watch(function() { return element.parent().height(); }, function (val) { console.log('height changed to: ' + val); scope.map.invalidateSize(); }); }, scope: true, 

Make your controller installed $scope.map = L.map('map',{crs: L.CRS.EPSG4326}).setView([0,0], 4); so that the sheet map object is in scope and remove the css rules that you have on .map-content

+5
source

I had a similar problem. What happens is that when the directives were loaded, the post-link function calculated the clientHeight value of the div element. Div fills the remaining space with flex. But there was always nothing to it. I tracked it to angular by calling the link for the message before all partial parts of the template were received from the web server. Another directive was still waiting for its urlTemplate, and as soon as it entered, this directive caused another div to change the height.

If I just set the timeout enough time, this will work on the problem. Also, if I broadcast an event from the last div and expect this before calculating the height, this will also work around the problem.

I could not find an easy way to tell when all the templates were loaded and all the directives did their job with the DOM. The priorities of the directives have not changed anything to change the order of things.

Look at the sequence of events in the browser and see if it is an incomplete template that arrives late, which throws time too quickly so that the calculations are not performed exactly when you asked them to be done.

+2
source

Edited plunkr: http://plnkr.co/edit/pIg9HKwkl0Bfhk4N3wQX?p=preview

try installing the card as follows:

 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 } }]); 
+1
source

Source: https://habr.com/ru/post/1246260/


All Articles