传单地图中的奇怪默认大小

Strange default size in leaflet map

我拍了一张有效的 Leaflet 地图,但是当我添加 JQuery 移动 header 和后退按钮时,格式变得疯狂了。

最初加载页面时,所有内容都加载在 upper-left-hand 角落,但是当页面在桌面上调整到最小位,或在移动设备上旋转时,一切都很好。

这是打开后的样子:

以及旋转后的样子(以及应该的样子):

这是页面的代码

<!DOCTYPE html>
<html>
<head>
<title>Toronto CAD Activity Map</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../css/leaflet.css" />
 <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../css/tfscad.mobile.css" />
<link rel="stylesheet" href="../css/jquery.mobile-1.4.5.min.css">
<link rel="stylesheet" href="../css/font-awesome.min.css">
<script src="../js/jquery-1.11.1.min.js"></script>
<script src="../js/jquery.mobile-1.4.5.min.js"></script>
<script src="../js/iframeResizer.contentWindow.js"></script>

<!--[if lte IE 8]><link rel="stylesheet" href="../dist/leaflet.ie.css" /><![endif]-->
<style>
#mapPage {
  height: calc(100% - 42px);
}

#map {
  height: 100%;
}

#map-content{
  height: 100%;
  padding: 0px; 
  margin:0px;
  z-index: -1;
}
#curLoc{
  position: absolute;
  bottom: 0;
  left: 10px;
}
</style>
</head>


<body>
<body>
    <div data-role="page" id="mapPage" data-theme="a"> 
        <div data-role="header" data-position="fixed" data-theme="a">
            <a id="backButton" href="#" data-rel="back" 
                data-transition="slide" data-direction="reverse">Back</a>
            <h1>Toronto CAD Map</h1>
        </div> 

        <div id="map-content" data-role="content">
            <div id="map"></div>
        </div>
        <a id="curLoc" data-role="button" data-icon="location" data-iconpos="notext"></a>

    </div> 
<script src="../js/jquery-1.11.1.min.js"></script> 
<script src="../js/leaflet.js"></script> 

<script type="text/javascript">
 window.onload = function() {
getGeoJson();
getTPSJson();
};
 
    var map = L.map('map').setView([43.7178,-79.3762], 11);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2012 CloudMade',
               }).addTo(map);



function getGeoJson(){
 
  // load GeoJSON from an external file
  $.getJSON("../appdata/geo.json",function(data){

      L.geoJson(data  ,{
    pointToLayer: function(feature,latlng){
       
       var TFS = new L.icon({
       iconUrl: '../images/tfs_logo.png',
      iconSize:     [22, 22],
      popupAnchor:  [0, -22]
      });

     var TPS = new L.icon({
       iconUrl: '../images/tps_logo.png',
      iconSize:     [22, 22],
      popupAnchor:  [0, -22]
      });

     var ESC = new L.icon({
       iconUrl: '../images/tps_logo.png',
      iconSize:     [22, 22],
      popupAnchor:  [0, -22]
      });         
 if(feature.properties.icon == 'TFS'){
    var marker = L.marker(latlng,{icon: TFS});
  marker.bindPopup('<strong>' + feature.properties.event_type + '</strong><br/>' + feature.properties.OPEN_DT);
  return marker; 
    
  }else if(feature.properties.icon == 'TPS'){
    var marker = L.marker(latlng,{icon: TPS});
  marker.bindPopup('<strong>' + feature.properties.event_type + '</strong><br/>' + feature.properties.OPEN_DT);
  return marker; 

  }else if(feature.properties.icon == 'ESC'){    
    var marker = L.marker(latlng,{icon: ESC});
  marker.bindPopup('<strong>' + feature.properties.event_type + '</strong><br/>' + feature.properties.OPEN_DT);
  return marker; 
  }
      }
  }  ).addTo(map);
  }); 
 
 
}

function getTPSJson(){
 
var myStyle = {
  "color": "#ff7800",
  "weight": 5,
  "opacity": 0,
  "offset": 1.5
};

  // load GeoJSON from an external file
  $.getJSON("../appdata/TPSDiv.json",function(myLines){

 L.geoJson(myLines, {
style: myStyle
}).addTo(map);
})
}


 setInterval(function()
{ 
 
getGeoJson();

}, 10000);//time in milliseconds  

    function onClick(e) {
        //console.log(this.options.win_url);
        window.open(this.options.win_url);
    }
 
    
</script>
</body>

jQuery Mobile 管理多页文档的页面并在加载 DOM 时适当调整它们的大小。

问题是您已经在该事件发生之前用 Leaflet 实例化了 map,因此 jQuery Mobile 尚未显示地图容器(即 <div id="map"></div>),因此它的大小还没有被浏览器计算出来。

这是地图容器大小的变体,在地图实例化时尚未生效。参见

因为您已经在 window.onload 上有一个侦听器,它会在 jQuery Mobile 完成它的工作后执行,您可以非常简单地调用 map.invalidateSize() 那一刻:

window.onload = function() {

  // Request Leaflet to re-evaluate the map container size
  // AFTER jQuery Mobile displays the page.
  map.invalidateSize();

  getGeoJson();
  getTPSJson();
};

演示:https://plnkr.co/edit/TigW44s5MlqMifimWkSw?p=preview

jQuery 移动设备有自己的方式从 div 创建页面,因此您最好坚持使用 JQM 事件。

Here is a great post of Omar 解释了加载 Google 地图时如何解决这个(典型)问题。您应该等待 pagecontainershow 或使用占位符提前预加载地图。

在我下面的示例中,您会发现 Leaflet 的这种方法的变体,它使用相同的 canvasHeight() 函数(另请参阅此处的答案:set content height 100% jquery mobile)。

我注意到您即将为地理位置功能实现一个页脚按钮,因此为了您的方便,我还向您展示了一种可能的方法(致谢:Getting current user location automatically every “x” seconds to put on Leaflet map?)。

请注意:我必须重新定位默认地图属性,使其不会与页脚按钮重叠。

var map, actualPosition, actualAccuracy, autoUpdate;

function canvasHeight(canvas) {
  var mapPage = $("#page-map"),
    screen = $.mobile.getScreenHeight(),
    header = $(".ui-header", mapPage).hasClass("ui-header-fixed") ? $(".ui-header", mapPage).outerHeight() - 1 : $(".ui-header", mapPage).outerHeight(),
    footer = $(".ui-footer", mapPage).hasClass("ui-footer-fixed") ? $(".ui-footer", mapPage).outerHeight() - 1 : $(".ui-footer", mapPage).outerHeight(),
    newHeight = screen - header - footer;
  $(canvas).height(newHeight);
}

$(window).on("throttledresize orientationchange", function() {
  canvasHeight("#map");
})

function onLocationFound(e) {
  var radius = e.accuracy / 2;
  actualPosition = L.marker(e.latlng).addTo(map);
  actualAccuracy = L.circle(e.latlng, radius).addTo(map);
}

function onLocationError(e) {
  alert(e.message);
}

function showLocation() {
  if (actualPosition) {
    map.removeLayer(actualPosition);
    map.removeLayer(actualAccuracy);
  }
  map.locate({setView: true,maxZoom: 16});
}

function loadMap(canvas) {
  map = L.map(canvas).setView([43.7178, -79.3762], 11);
  L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png").addTo(map);
  map.on('locationfound', onLocationFound);
  map.on('locationerror', onLocationError);
  // Your custom initialization
  //getGeoJson();
  //getTPSJson();
}

function toggleAutoUpdate() {
  if (autoUpdate) {
    $("#autoUpdate").removeClass("ui-btn-active");
    clearInterval(autoUpdate);
    autoUpdate = null;
    if (actualPosition) {
      map.removeLayer(actualPosition);
      map.removeLayer(actualAccuracy);
    }
  } else {
    $("#autoUpdate").addClass("ui-btn-active");
    showLocation();
    autoUpdate = setInterval(function() {
      showLocation();
      // Your custom Update
      //getGeoJson();
    }, 10 * 1000);
  }
}

$(document).on("pagecontainershow", function(e, ui) {
  if (ui.toPage.prop("id") == "page-map") {
    canvasHeight("#map");
    if (!map) {
      loadMap("map");
    }
  }
});
#map {
  margin: 0;
  padding: 0;
}

#page-map .footer {
  position: fixed;
  z-index: 1000;
  bottom: .1em;
  width: 100%;
}

#footer-button {
  width: 100%;
  text-align: center;
  background: transparent;
}

#map-attribution {
  text-align: center;
  background: rgba(255, 255, 255, 0.7);
}

.leaflet-control-attribution.leaflet-control {
  display: none;
}

/* Don't show scrollbars on SO code snippet */
.ui-mobile .ui-page {
  min-height: 100px !important;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.1.0/leaflet.css">
  <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
  <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.1.0/leaflet.js"></script>
</head>
<body>
  <div data-role="page" id="page-map">
    <div data-role="header" data-position="fixed" data-theme="a">
      <a href="#" data-rel="back" data-transition="slide" data-direction="reverse">Back</a>
      <h1>Toronto CAD Map</h1>
    </div>

    <div id="map" data-role="content">
      <div class="footer">
        <div id="footer-button">
          <button id="autoUpdate" onclick="toggleAutoUpdate();" class="ui-btn ui-btn-inline ui-corner-all ui-icon-location ui-btn-icon-notext"></button>
        </div>
        <div id="map-attribution">
          <a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a> Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2012 CloudMade
        </div>
      </div>
    </div>
  </div>
</body>
</html>