【问题标题】:Render leaflet map after flexbox calculates heightflexbox计算高度后渲染传单地图
【发布时间】:2016-07-21 15:28:58
【问题描述】:

我正在尝试在占用剩余空间的 flex child 中绘制地图。

我在主要内容的顶部有几个标题,其中一个横幅有时被隐藏/删除,所以我使用 flexbox 以便标题可以在不影响其他元素位置的情况下消失。即当我使用绝对位置时,这不起作用。

我的问题是,在 flexbox 计算地图 div 的高度之前,leaflet 似乎正在计算地图视口。

例子:

这是一张传单认为地图高度小于应有高度的屏幕截图。

如果我检查元素高度,它是正确的。此外,如果我放入计时器并强制传单使地图大小无效,则地图会在正确的高度重新渲染。

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。

这是坏掉的笨蛋。在初始页面加载时,地图很好。单击关于链接,然后返回地图。请注意,返回时,只有大约一半的地图加载。我将高度记录到控制台。当您导航离开地图并返回时,其大小始终约为一半。

angular animate 做了什么来使元素在一瞬间缩小一半?这是角度的错误吗?

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

【问题讨论】:

  • #map 的大小会在您单击“关于”后立即更改,如下图所示:plnkr.co/edit/NRTW4TL29yc36omsbJ9M?p=preview
  • 正确。很好的发现。如果我不将 ngAnimate 注入到我的应用程序中,则地图 div 将不再在 about 页面中可用。这似乎是错误的,为什么当我将 angular-animate 注入我的应用程序时,那个 div 会停留在新的路线上?

标签: css angularjs leaflet flexbox angularjs-animation


【解决方案1】:

看起来传单地图在创建时获得了高度,然后如果高度发生变化,您需要调用.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 规则

【讨论】:

【解决方案2】:

我遇到了类似的问题。发生的事情是,在加载指令时,一个 post 链接函数计算了 div 元素的 clientHeight。 div 用 flex 填充剩余空间。但它总是偏离了一些。在从 Web 服务器检索到所有模板部分之前,我将其跟踪到 Angular 调用 post 链接。另一个指令还在等待它的 urlTemplate,一旦它进来,那个指令就会导致另一个 div 改变高度。

如果我只是设置了足够的超时时间,它就可以解决问题。此外,如果我从后期 div 广播一个事件并在计算高度之前等待该事件,这也可以解决问题。

我找不到一种简单的方法来判断所有模板何时已加载,并且所有指令都已完成操作 DOM 的操作。指令优先级完全没有改变事情的顺序。

查看浏览器中的事件序列,看看是不是部分模板迟到导致时间不够,以至于在您要求执行计算时无法准确执行。

【讨论】:

    【解决方案3】:

    已编辑 plunkr:http://plnkr.co/edit/pIg9HKwkl0Bfhk4N3wQX?p=preview

    尝试像这样“使”地图“无效”:

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

    【讨论】:

    • 这是一个选项,但充其量是一种解决方法。为什么包含 ngAnimate 会导致该 div 不会消失并因此在我转到另一条路线时改变大小。
    • 据我所知,当地图被隐藏然后重新显示时(例如手风琴中的 css),我遇到了传单的问题。这是我找到的唯一解决方案。也许 ngAnimate 隐藏/显示 div 而不重建它。我关注您的帖子以查看更好的解决方案;)
    猜你喜欢
    • 2017-09-01
    • 1970-01-01
    • 2023-03-14
    • 2020-05-01
    • 2016-12-29
    • 2022-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多