OpenLayers 3 not showing on a simple modal

2019-09-03 16:46发布

I'm trying to display a map using OpenLayers 3 and the SimpleModal plugin for jQuery. When I click my link, the modal opens but the map isn't showing. What am I missing?

I've reproduced my problem on JSBin, http://jsbin.com/hunexepeti/2/edit?html,js,output

This is the HTML relevant part,

<a id="open-map" href="#">Open map</a>
<div id="map"></div>

and this is my JS,

function initMap(lat, lon) {
    var container = document.getElementById('map');
    var map = new ol.Map({ 
      layers: [ 
        new ol.layer.Tile({ 
          source: new ol.source.Stamen({
            layer: 'toner'
          })
        })
      ], 
      renderer: 'canvas',
      target: container, 
      view: new ol.View({ 
        center: [lat, lon], 
        zoom: 2 
      }) 
    }); 
  }

$(document).on('click', 'a#open-map', function(e) {
  e.preventDefault();

  var pos = {
    lat: 0,
    lon: 0
  };

  $("#map").modal({ 
    onOpen: function (dialog) {
      dialog.overlay.fadeIn('fast', function () {
        dialog.data.hide();
        dialog.container.fadeIn('fast', function () {
          dialog.data.slideDown('fast');     
        });
      });
      initMap(pos.lat, pos.lon);
    },
    onClose: function (dialog) {
      dialog.data.fadeOut('fast', function () {
        dialog.container.hide('fast', function () {
          dialog.overlay.slideUp('fast', function () {
            $.modal.close();
          });
        });
      });
    },
    overlayClose: true
  });
});

EDIT: It is fixed, thanks to @ekuusela answer. However I have several location links, so I need to open different locations into the modal.

  • Should I reuse the same map and change its View?
  • or could I create a new one with a new View because the older is overwritten? I'm curious about performance.

2条回答
啃猪蹄的小仙女
2楼-- · 2019-09-03 17:32

You need to call initMap after the animations are finished, so in the slideDown animation's callback.

The slideDown animation of course won't show anything if you init the map after it's been completed. You could modify the onOpen to be something like this:

onOpen: function (dialog) {
  dialog.overlay.fadeIn('fast', function () {
    dialog.data.hide();
    dialog.container.fadeIn('fast', function () {
      dialog.data.show(); // show just so we can init the map properly
      initMap(pos.lat, pos.lon);
      dialog.data.hide().slideDown('fast');  
    });
  });

Alternatively, OpenLayers 3 might have some properties you can set to the view to make it ignore container visibility and dimensions on initialize.

查看更多
做自己的国王
3楼-- · 2019-09-03 17:37

I got the solution create your own modal. the html :

<a href="#openModal">
<div id="openModal" class="modalDialog">
                <div>
                    <a href="#close" title="Close" class="close">X</a>
                    <div id="map" class="map" data-role="map"></div>
                </div>
            </div>

the css : .modalDialog { position: fixed; font-family: Arial, Helvetica, sans-serif; top: 0; right: 0; bottom: 0; left: 0; background: rgba(0,0,0,0.8); z-index: 99999; opacity:0; -webkit-transition: opacity 400ms ease-in; -moz-transition: opacity 400ms ease-in; transition: opacity 400ms ease-in; pointer-events: none; } .modalDialog:target { opacity:1; pointer-events: auto; }

.modalDialog > div {
    width: 90%;
    position: relative;
    margin: 3% auto;
    background: #fff;
}
.close {
    background: #606061;
    color: #FFFFFF;
    line-height: 25px;
    position: absolute;
    right: -12px;
    text-align: center;
    top: -10px;
    width: 24px;
    text-decoration: none;
    font-weight: bold;
    -webkit-border-radius: 12px;
    -moz-border-radius: 12px;
    border-radius: 12px;
    z-index: 9999;
}
.close:hover { background: #00d9ff; }

initialize your openlayer :

function initialize(url) { document.getElementById('map') //etc //byId }

then you must set the height for the map in your modal :

function fixContentHeight(){
    var viewHeight = $(window).height();
    var maps = $("div[data-role='map']:visible:visible");

    var contentHeight = viewHeight;
    maps.height(contentHeight);
}
fixContentHeight();

hope it can helps...

查看更多
登录 后发表回答