Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
258 views
in Technique[技术] by (71.8m points)

html - jquery mobile google maps showing intermittently

Hi guys after fixing one problem with the project I'm working on I've hit another on, now I know this question as been asked quite a good few times but the solutions I have found don't seem to make a difference.

So I'm basically trying to integrate a get directions kind of function into my app, which I have basically taken from the demos of the API, It works perfectly on its own but when I add it to the code it works very very very intermittently, sometimes its there sometimes its not and sometimes its half there and only shows fully when refreshed .

I have included the main parts of the code below that relate to this section of the project help would be appreciated.

This is a reduced form of the HTML

 <html lang ="en">
 <head>
    <meta charset ="utf-8"/>
    <meta content="en" http-equiv="content-language">
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
    <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
    <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3&sensor=false&language=en"></script>
        </head>
<body>
    <div data-role ='page' id = "Archaeology"  data-theme ="b" > 

        <header data-role = "header">
            <h1>The National Museum of Archaeology</h1>
            <a href='#Museums' data-icon = 'back'>Back</a>
        </header>

        <p>The national repository for all archaeological objects found in Ireland and home to over two million artefacts. </p>

        <div data-role="content" >
            <div id="container">    
                <img src="ARchBackground.jpg" style= "height:100%; width: 100%;"/>
            </div>
        </div>



        <ul data-role = "listview">

            <li>
            </li>

            <li>
            </li>

            <li>
            </li>

            <li>
                <a href="#Archmap_page" data-theme="" id="arch_gmap"> <img src="arch.gif" width="150" height="150" rel="external" > <br/> Find us on google maps </a>
            </li>

        </ul

        <div data-role="page" id="Archmap_page">
    <header data-role = "header">
        <h1>The National Museum of Archaeology</h1>
        <a href='#Archaeology' data-icon = 'back'>Back</a>
    </header>
        <div data-role="content">
            <div class="ui-bar-c ui-corner-all ui-shadow" style="padding:1em;">
                <div id="map_canvas" style="height:200px; width: 500px;"></div>
                <div data-role="fieldcontain">
                    <label for="from">From</label> 
                    <input type="text" id="from" value="Enter your location here"/>
                </div>
                <div data-role="fieldcontain">
                    <label for="to">To</label> 
                    <input type="text" id="to" value="The National Museum of Ireland, Archaeology "/>
                </div>
                <div data-role="fieldcontain">
                    <label for="mode" class="select">Transportation method:</label>
                    <select name="select-choice-0" id="mode">
                        <option value="DRIVING">Driving</option>
                        <option value="WALKING">Walking</option>
                        <option value="BICYCLING">Bicycling</option>
                    </select>
                </div>
                <a data-icon="search" data-role="button" href="#" id="submit">Get directions</a>
            </div>
            <div id="results" style="display:none;">
                <div id="directions"></div>
            </div>
        </div>
    </div>

Below is the javscript

        $(document).delegate('#Archmap_page', 'pageinit', function () {
            navigator.geolocation.getCurrentPosition(initialize);
        });

        $(document).on('click', '#submit', function(e) {
            e.preventDefault();
            calculateRoute();
        });

        var directionDisplay,
            directionsService = new google.maps.DirectionsService(),
            map;

        function initialize() 
        {
            directionsDisplay = new google.maps.DirectionsRenderer();
            var mapCenter = new google.maps.LatLng(53.340617, -6.255244);

            var myOptions = {
                zoom:30,
                mapTypeId: google.maps.MapTypeId.ROADMAP,
                center: mapCenter
            }

            map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
            directionsDisplay.setMap(map);
            directionsDisplay.setPanel(document.getElementById("directions"));  
        }

        function calculateRoute() 
        {
            var selectedMode = $("#mode").val(),
                start = $("#from").val(),
                end = $("#to").val();

            if(start == '' || end == '')
            {
                // cannot calculate route
                $("#results").hide();
                return;
            }
            else
            {
                var request = {
                    origin:start, 
                    destination:end,
                    travelMode: google.maps.DirectionsTravelMode[selectedMode]
                };

                directionsService.route(request, function(response, status) {
                    if (status == google.maps.DirectionsStatus.OK) {
                        directionsDisplay.setDirections(response); 
                        $("#results").show();
                        /*
                            var myRoute = response.routes[0].legs[0];
                            for (var i = 0; i < myRoute.steps.length; i++) {
                                alert(myRoute.steps[i].instructions);
                            }
                        */
                    }
                    else {
                        $("#results").hide();
                    }
                });

            }
        }
    </script>

I have seen solutions that advise adding things like rel="external" in the anchor tags linking to a page with a google map. Can anyone shed some light on this I know its been asked before, but I wouldn't describe myself as good as javascript its more just a copy and paste job for me here.

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is common difficulty most of developers face when using jQuery Mobile and Google Maps. jQuery Mobile is based on Ajax navigation to load, render and show pages. Unlike HTTP, where all elements are loaded and shown at once.

A page in jQuery Mobile passes through several page events, it starts with pagebeforecreate and ends with pageshow -pagechange is last but rarely used-. During those events, a page gets enhanced/rendered but still not fully ready to be shown, as height of main divs is still unset.

However, on pageshow height of main divs is set and defined, except for content div data-role="content" which depends on elements within.

This being said, initializing Google Maps should occur during pageshow event. Using any other event will load an incomplete map. Another note, height of content div should be reset in order to fully accommodate map. I have written in details a full solution for all jQuery Mobile versions.

CSS - Remove content's div padding and set map's div height and width.

#map-canvas {
  width: 100%;
  height: 100%;
}

.ui-content {
  padding: 0;
}

JS - Initialize map on pageshow event. If it's a full page map (no toolbars), reset content div's height and width based on viewport. Remember that content div's dimensions should be reset on orientationchange and throttledresize events.

$(document).on("pageshow", "#mapPage", function () {
  $(".ui-content", this).css({
    height: $(window).height(),
    width: $(window).width()
  });
  InitilizeMap();
});

You can also use .one() instead of .on() if you want to initialize it one time only.

Bonus - Back button for full page map, to be appended on idle event after map is fully initialized.

google.maps.event.addListenerOnce(map, 'idle', function (e) {
    $("#map-canvas").append($("<a href='#' data-role='button' data-rel='back' class='forMap'>Back</a>").hide().fadeIn(300));
    $(".forMap").buttonMarkup({
        mini: true,
        inline: true,
        corners: false
    });
});
google.maps.event.addListener(map, 'dragstart', function (e) {
    $(".forMap").animate({
        "opacity": 0.3
    }, 300);
});

google.maps.event.addListener(map, 'dragend', function (e) {
    $(".forMap").animate({
        "opacity": 1
    }, 700);
});

Back button CSS

.forMap {
  position: absolute;
  top:0;
  left:0;
}

Demo


References:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...