【问题标题】:Strange default size in leaflet map传单地图中奇怪的默认大小
【发布时间】:2017-07-22 08:38:24
【问题描述】:

我已经使用了一张有效的传单地图,但是当我添加一个 JQuery Mobile 标题和后退按钮时,格式变得疯狂。

最初加载页面时,所有内容都加载在左上角,但是当页面在桌面上调整为最小的位时,或者在移动设备上旋转时,一切都很好。

这是打开后的样子:

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

这是页面的代码

<!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 leaflet


【解决方案1】:

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

HereOmar 的一篇很棒的帖子,它解释了如何在加载谷歌地图时解决这个(典型的)问题。您应该等待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>

【讨论】:

  • 感谢您为回答所做的所有工作!现在完美运行。
【解决方案2】:

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

问题是您已经在该事件发生之前使用 Leaflet 实例化了您的 map,因此 jQuery Mobile 尚未显示地图容器(即 &lt;div id="map"&gt;&lt;/div&gt;),因此其大小尚未由浏览器。

这是地图容器大小的变体,在地图实例化时尚未生效。见Data-toggle tab does not download Leaflet map

由于您已经在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

【讨论】:

    猜你喜欢
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多