有没有办法用 jquery mobile 预加载谷歌地图? [英] Is there a way to preload google map with jquery mobile?

查看:18
本文介绍了有没有办法用 jquery mobile 预加载谷歌地图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

带有 jQ​​uery Mobile 1.4 和 Google Maps JavaScript API v3 的 Phonegap 应用.

地图需要几秒钟才能加载到移动设备上,有时会更长.我正在尝试预加载"地图页面,以便在用户导航到该页面时立即显示.

我尝试过的一些不成功的事情:

$.mobile.pageContainer.enhanceWithin();在应用加载时创建页面.它会创建地图,但不会显示地图,除非在页面显示时触发调整大小.

在应用加载时创建地图,然后在页面展示时触发地图大小调整,从而刷新地图大小.可能会快一点,但还是需要等待,因为原始地图没有渲染正确的大小,所以你需要调整大小.

手动设置地图容器的 css 高度/宽度并在应用程序启动时加载地图.正确的容器大小,但仍需要触发调整大小.

最佳解决方案是在应用加载时在后台加载完整的地图页面(加上一些额外的图块,以防它们滚动),然后当用户导航到它时,它已经传播了.

解决方案

您可以通过在第一页完全加载并显示后加载 地图画布 来实现此目的.但是,地图画布应该放在在当前视口可见的div中.在 地图画布 上使用 display: none; 会破坏结构,并在将其从 div 移动到另一个 div 时变得无响应.

另一个重要的注意事项,在创建页面之前和之后,内容 div 的高度总是0.因此,content div 的高度应该预先定义,以便在后台加载后容纳地图画布.

  • 第一步:

    在任何页面div之外创建一个地图占位符,并通过改变它的位置确保它不在viewport视图内 CSS 属性.在地图占位符中,添加地图画布 div.此外,删除 content div padding 以填充整个可用区域.

    • HTML

      <div id="map-canvas"></div>

    • CSS

      #mapPH {位置:绝对;顶部:-999;z-索引:-9999;}.ui-内容{填充:0;}

  • 第二步:

    在任何 jQM 的页面事件上,仅将地图加载到 地图画布一次.one().完全加载后,移至其新父级.您可以通过监听 tilesloaded 事件在加载后自动移动它,或者移动它一次以更改为 map 页面.

    var mapOptions = {中心:新的 google.maps.LatLng(36.4875, -4.9525),缩放:16,mapTypeId: google.maps.MapTypeId.HYBRID,地图类型控制:假,街景控制:假,缩放控制选项:{位置:google.maps.ControlPosition.RIGHT_BOTTOM}};var map = new google.maps.Map($(canvas)[0],地图选项);var 标记 = 新的 google.maps.Marker({位置:新 google.maps.LatLng(36.4875, -4.9525),地图:地图,标题:世界你好!"});/* 完全加载后移动地图通过听tilesloaded".移动地图后删除占位符"*/google.maps.event.addListener(map, 'tilesloaded', function () {$("#map .ui-content").append($("#mapPH #map-canvas"));$("#mapPH").remove();});/* 或选择任何其他方法来移动它 */$(".selector").on("click", function () {$("#map .ui-content").append($("#mapPH #map-canvas"));$("#mapPH").remove();});

  • 第三步:

    这里是棘手的部分,地图画布的尺寸(宽度和高度).正如我之前提到的,content div 的高度应该使用以下函数手动或动态预定义.

    function canvasHeight(canvas) {/* canvas = 地图的画布 ID */var canvasPage = $(canvas).closest("[data-role=page]").length !== 0 ?$(canvas).closest("[data-role=page]") : $(".ui-page").first(),屏幕 = $.mobile.getScreenHeight(),header = $(".ui-header", canvasPage).hasClass("ui-header-fixed") ?$(".ui-header", canvasPage).outerHeight() - 1 : $(".ui-header", canvasPage).outerHeight(),footer = $(".ui-footer", canvasPage).hasClass("ui-footer-fixed") ?$(".ui-footer", canvasPage).outerHeight() - 1 : $(".ui-footer", canvasPage).outerHeight(),newHeight = 屏幕 - 页眉 - 页脚;$(canvas).height(newHeight);$(canvas).width($(window).width());}

    应该在加载地图画布以及移动它时调用该函数.但是,要获得实际尺寸,此处需要 setTimeout(),因为您要移动到的页面仍未创建.如果页面不是创建,您将不会获得该页面中元素的实际/真实高度.

    更新:地图画布的尺寸应该在两个事件上更新,throttledresizeorientationchange.

    $(window).on("throttledresizeorientationchange", function () {canvasHeight("#map-canvas");});

<小时>

这里是完整的代码以供更多说明.

/* 映射画布尺寸 */功能画布高度(画布){var canvasPage = $(canvas).closest("[data-role=page]").length !== 0 ?$(canvas).closest("[data-role=page]") : $(".ui-page").first(),屏幕 = $.mobile.getScreenHeight(),header = $(".ui-header", canvasPage).hasClass("ui-header-fixed") ?$(".ui-header", canvasPage).outerHeight() - 1 : $(".ui-header", canvasPage).outerHeight(),footer = $(".ui-footer", canvasPage).hasClass("ui-footer-fixed") ?$(".ui-footer", canvasPage).outerHeight() - 1 : $(".ui-footer", canvasPage).outerHeight(),newHeight = 屏幕 - 页眉 - 页脚;$(canvas).height(newHeight);$(canvas).width($(window).width());}/* 地图画布加载 */功能加载映射(画布){var mapOptions = {中心:新的 google.maps.LatLng(36.4875, -4.9525),缩放:16,mapTypeId: google.maps.MapTypeId.HYBRID,地图类型控制:假,街景控制:假,缩放控制选项:{位置:google.maps.ControlPosition.RIGHT_BOTTOM}};var map = new google.maps.Map($(canvas)[0],地图选项);var 标记 = 新的 google.maps.Marker({位置:新 google.maps.LatLng(36.4875, -4.9525),地图:地图,标题:世界你好!"});/* 选项 1:加载后移动地图 */google.maps.event.addListener(map, 'tilesloaded', function () {$("#map .ui-content").append($("#mapPH #map-canvas"));$("#mapPH").remove();});}/* 在后台加载地图一旦显示第一页并更新其尺寸 */$(document).one("pagecontainershow", function () {canvasHeight("#map-canvas");loadMap("#map-canvas");/* 选项 2:在点击"时移动地图并更新其尺寸 */$(".showMap").one("点击", function () {$("#map .ui-content").append($("#mapPH #map-canvas"));设置超时(函数(){canvasHeight("#map-canvas");}, 500);$("#mapPH").remove();});});/* 更新地图画布尺寸当窗口调整大小并改变方向时 */$(window).on("throttledresizeorientationchange", function () {canvasHeight("#map-canvas");});

<块引用>

演示

Phonegap app with jQuery Mobile 1.4 and Google Maps JavaScript API v3.

The map takes a couple seconds to load on a mobile device, sometimes longer. I'm trying to "preload" the map page so it appears instant when the user navigates to the page.

Some things I've tried unsuccessfully:

$.mobile.pageContainer.enhanceWithin();to create pages on app load. It creates the map, but no map display unless resize triggered on pageshow.

Creating map on app load, then triggering a map resize on pageshow, so it refreshes map size. Maybe a bit faster, but still need to wait, as original map not rendered correct size, so you need to resize.

Manually set css height/width of the map container and load map on app startup. Correct container size, but still need to trigger resize.

Optimal solution is to load the full map page (plus some extra tiles in case they scroll) in the background on app load, then when user navigates to it, it's already propagated.

解决方案

You can achieve this by loading map canvas once first page is fully loaded and shown. However, map canvas should be placed in a div that isn't visible in current viewport. Using display: none; on map canvas will break the structure and becomes unresponsive when you move it from div to another.

Another important note, height of content div are always 0 before and after creating a page. Hence, content div's height should be predefined in order to accommodate map canvas after it is loaded in background.

  • First step:

    Create a map placeholder outside any page div, and make sure it isn't within viewport view by changing it's position CSS property. Inside map placeholder, add map canvas div. Moreover, remove content div padding to fill the whole available area.

    • HTML

      <div id="mapPH">
        <div id="map-canvas"></div>
      </div>
      

    • CSS

      #mapPH {
        position: absolute;
        top:-999;
        z-index: -9999;
      }
      
      .ui-content {
        padding: 0;
      }
      

  • Second step:

    On any jQM's page events, load map into map canvas ONLY one time .one(). Once it fully loaded, move to its' new parent. You can either move it automatically once loaded by listening to tilesloaded event, or move it once to change to map page.

    var mapOptions = {
        center: new google.maps.LatLng(36.4875, -4.9525),
        zoom: 16,
        mapTypeId: google.maps.MapTypeId.HYBRID,
        mapTypeControl: false,
        streetViewControl: false,
        zoomControlOptions: {
            position: google.maps.ControlPosition.RIGHT_BOTTOM
        }
    };
    var map = new google.maps.Map($(canvas)[0],
    mapOptions);
    var marker = new google.maps.Marker({
        position: new google.maps.LatLng(36.4875, -4.9525),
        map: map,
        title: 'Hello World!'
    });
    
    /* move map once fully loaded
       by listening to "tilesloaded".
       Remove "placeholder" after moving the  map */
    google.maps.event.addListener(map, 'tilesloaded', function () {
        $("#map .ui-content").append($("#mapPH #map-canvas"));
        $("#mapPH").remove();
    });
    
    /* or choose any other method to move it */
    $(".selector").on("click", function () {
      $("#map .ui-content").append($("#mapPH #map-canvas"));
      $("#mapPH").remove();
    });
    

  • Third step:

    Here comes the tricky part, map canvas's dimensions (width & height). As I've mentioned before, content div's height should either predefined manually or dynamically using the below function.

    function canvasHeight(canvas) { /* canvas = map's canvas ID */
        var canvasPage = $(canvas).closest("[data-role=page]").length !== 0 ? $(canvas).closest("[data-role=page]") : $(".ui-page").first(),
            screen = $.mobile.getScreenHeight(),
            header = $(".ui-header", canvasPage).hasClass("ui-header-fixed") ? $(".ui-header", canvasPage).outerHeight() - 1 : $(".ui-header", canvasPage).outerHeight(),
            footer = $(".ui-footer", canvasPage).hasClass("ui-footer-fixed") ? $(".ui-footer", canvasPage).outerHeight() - 1 : $(".ui-footer", canvasPage).outerHeight(),
            newHeight = screen - header - footer;
        $(canvas).height(newHeight);
        $(canvas).width($(window).width());
    }
    

    That function should be called once map canvas is loaded as well as when moving it. However, to get actual dimensions, a setTimeout() is required here, since the page you're moving to is still not created. When a page isn't created, you won't get actual/true height of elements within that page.

    Update: map canvas's dimensions should be updated on two events, throttledresize and orientationchange.

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


Here is the complete code for more clarification.

/* map canvas dimensions */
function canvasHeight(canvas) {
    var canvasPage = $(canvas).closest("[data-role=page]").length !== 0 ? $(canvas).closest("[data-role=page]") : $(".ui-page").first(),
        screen = $.mobile.getScreenHeight(),
        header = $(".ui-header", canvasPage).hasClass("ui-header-fixed") ? $(".ui-header", canvasPage).outerHeight() - 1 : $(".ui-header", canvasPage).outerHeight(),
        footer = $(".ui-footer", canvasPage).hasClass("ui-footer-fixed") ? $(".ui-footer", canvasPage).outerHeight() - 1 : $(".ui-footer", canvasPage).outerHeight(),
        newHeight = screen - header - footer;
    $(canvas).height(newHeight);
    $(canvas).width($(window).width());
}

/* map canvas loading */
function loadMap(canvas) {
    var mapOptions = {
        center: new google.maps.LatLng(36.4875, -4.9525),
        zoom: 16,
        mapTypeId: google.maps.MapTypeId.HYBRID,
        mapTypeControl: false,
        streetViewControl: false,
        zoomControlOptions: {
            position: google.maps.ControlPosition.RIGHT_BOTTOM
        }
    };
    var map = new google.maps.Map($(canvas)[0],
    mapOptions);
    var marker = new google.maps.Marker({
        position: new google.maps.LatLng(36.4875, -4.9525),
        map: map,
        title: 'Hello World!'
    });
    /* option 1: moving map once loaded */ 
    google.maps.event.addListener(map, 'tilesloaded', function () {
        $("#map .ui-content").append($("#mapPH #map-canvas"));
        $("#mapPH").remove();
    });
}

/* load map in background
   once first page is shown 
   and update its' dimensions */
$(document).one("pagecontainershow", function () {
    canvasHeight("#map-canvas");
    loadMap("#map-canvas");

    /* option 2: move map on "click" 
       and update its' dimensions */
    $(".showMap").one("click", function () {
        $("#map .ui-content").append($("#mapPH #map-canvas"));
        setTimeout(function () {
            canvasHeight("#map-canvas");
        }, 500);
        $("#mapPH").remove();
    });
});

/* update map canvas dimensions
   when window is resized and changing orientation */
$(window).on("throttledresize orientationchange", function () {
  canvasHeight("#map-canvas");
});

Demo

这篇关于有没有办法用 jquery mobile 预加载谷歌地图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆