9

Pracuję nad optymalizacją witryny pod kątem urządzeń przenośnych. Mamy stronę Lokalizacja zawierającą informacje o lokalizacji i mapę lokalizacji za pomocą interfejsu Google Maps API. (v2 - Wiem, że jest przestarzałe, ale nie usprawiedliwiłem czasu na aktualizację, "jeśli nie jest zepsuty ..") Chcę użyć układu pojedynczej kolumny z podstawowymi informacjami, po której następuje mapa, a następnie więcej informacji.Umieść Mapy Google na stronie bez przesłonięcia zachowania przewijania iPhone'a

Teraz, gdy przewijam palcem stronę mobilną na iPhonie, po przejściu do mapy przewijanie strony zostanie przesłonięte, a mapa zacznie przesuwać. Jedynym sposobem, aby przewinąć stronę w dół, jest umieszczenie palca nad lub pod mapą, zakładając, że takie miejsce jest dostępne. Jeśli wyłączę przeciąganie mapy, to gdy zacznę przewijanie w dół i dojdę do mapy, nie przesuwa się ona, ale strona też nie przewija. Chciałbym potraktować mapę jako obraz statyczny, który mogę przewijać obok, ale nadal pozwalam przyciskom zoomu i pozwolić na przerysowanie mapy ze wskazówkami przez wybrane pole, które zakodowałem, więc literal static image nie jest rozwiązaniem.

Znalazłem this post that required similar functionality, ale używa v3. Myślę, że wszystko, co muszę zrobić, to "dodać zdarzenia dotykowe do kontenera mapy", ale nie znam tej części javascriptu, a to, co mam poniżej, nie pozwala na normalne przewijanie. Czy muszę ugryźć punkt na v3, czy mam błąd w dodawaniu zdarzeń dotykowych, który ma prostą korektę javascript, aby zrobić to, co chcę?

function initialize() { 
    if (GBrowserIsCompatible()) { 
    map = new GMap2(document.getElementById("map_canvas")); 
    geocoder = new GClientGeocoder(); 
    } 
} 

function showAddress(address, zoom) { 
//clipped... this part works fine 
} 

//These three lines create a map that my finger pans 
initialize(); 
showAddress("[clipped.. street, zip code]"); 
map.addControl(new GSmallZoomControl3D()); 

//This stops the map pan but still prevents normal page finger scrolling 
map.disableDragging(); 

//If done right could this allow normal page finger scrolling?? 
var dragFlag = false; 
map.addEventListener("touchstart", function(e){ 
    dragFlag = true; 
    start = (events == "touch") ? e.touches[0].pageY : e.clientY; 
},true); 
map.addEventListener("touchend", function(){ 
dragFlag = false; 
}, true); 
map.addEventListener("touchmove",function(
if (!dragFlag) return; 
end = (events == "touch") ? e.touches[0].pageY : e.clientY; 
window.scrollBy(0,(start - end)); 
}, true); 

Próbowałem również zastąpienie map.addEventListener z document.getElementById("map_canvas").addEventListener lub document.addEventListener bezskutecznie.

+0

Mapa jest wewnątrz iframe hostowane na Google i chyba coś jest Google niech Ci przełączać się za pomocą JavaScriptu, prawdopodobnie masz pecha. API v2 jest przestarzałe, więc jeśli znalazłeś coś, co działa w wersji 3, to dlaczego nie dokonać zmiany? API v3 ma znacznie więcej funkcji i jest łatwiejszy w użyciu, tak czy inaczej, IMHO. (Koniec z kluczem API dla jednego!) – Sparky

+0

Zacząłem zaglądać do v3 przed opublikowaniem tego. Żaden klucz API nie jest ładny, ale musimy użyć funkcji geokodowania, która wygląda tak, jak wymaga klucza API i wygląda na to, że jej odpowiedź jest bardziej złożona niż na v2, i mamy kilka innych stron, które również ją wykorzystują. Zasadniczo staram się uniknąć kilku godzin rekodowania dla v3 z szybką poprawką v2, ale jeśli to nie jest możliwe, poddam się i zrobię sensowną aktualizację. – joshuahedlund

+0

Zaktualizowałem teraz do wersji 3, ale nie mogę uruchomić zdarzeń dotykowych. Zajmuję się moim javascriptem w poszukiwaniu błędów, ale mam problemy z uzyskaniem dotykowych zdarzeń, by odpowiedzieć na cokolwiek. – joshuahedlund

Odpowiedz

18

Rozwiązałem go, aktualizując do wersji 3, a następnie wykrywając podstawowy błąd javascript podczas korzystania z kodu z rozwiązania powiązanego powyżej. Kluczem było

start = (events == "touch") ? e.touches[0].pageY : e.clientY; 

Użytkownik musi być ustawienie wydarzenia zmienna gdzieś poza prezentowanym kodzie, ponieważ wygląda na to zadanie jest dopasowanie do zdarzeń dotykowych i przypisanie innego jest dla kluczowych wydarzeń. Ale ponieważ nie miałem zmiennej zdarzenia, domyślnie było to niewłaściwe zadanie. Po prostu zmieniłem moje na start = e.touches[0].pageY (i zrobiłem to samo dla zdarzenia touchend) i teraz wszystko działa.

Jednak przełączyłem się z powrotem na v2, aby sprawdzić, czy zadziała z poprawionym błędem javascript, a tak się nie stało. Wygląda więc na to, że nie traciłem czasu na aktualizację do wersji 3, ani w szukaniu tego konkretnego rozwiązania, ani w ustawianiu się na przyszłe kompatybilności.

Podsumowując, jeśli chcesz osadzić Mapy Google na stronie mobilnej i móc przewijać obok niego, musisz użyć interfejsu API w wersji 3, wyłączyć przeciąganie i dodawać zdarzenia dotyku. Zrobiłem kilka drobnych poprawek w kodzie, jak również, przedstawiony tutaj dla każdego, kto może skorzystać w przyszłości:

function initialize() 
{ 
    geocoder = new google.maps.Geocoder(); 
    var myOptions = { 
     mapTypeId: google.maps.MapTypeId.ROADMAP    
    }; 

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

function showAddress(address, zoom) 
{ 
    if (geocoder) 
    { 
     geocoder.geocode({ 'address': address }, function (results, status) { 
     if (status == google.maps.GeocoderStatus.OK) { 
      map.setCenter(results[0].geometry.location); 
      map.setOptions({ zoom: zoom }); 
      var marker = new google.maps.Marker({ 
       map: map, 
       position: results[0].geometry.location 
      }); 
     } 
     }); 
    } 
} 

initialize(); 
showAddress("'.$geocode_address.'"); 

map.setOptions({ draggable: false }); 

var dragFlag = false; 
var start = 0, end = 0; 

function thisTouchStart(e) 
{ 
    dragFlag = true; 
    start = e.touches[0].pageY; 
} 

function thisTouchEnd() 
{ 
    dragFlag = false; 
} 

function thisTouchMove(e) 
{ 
    if (!dragFlag) return; 
    end = e.touches[0].pageY; 
    window.scrollBy(0,(start - end)); 
} 

document.getElementById("map_canvas").addEventListener("touchstart", thisTouchStart, true); 
document.getElementById("map_canvas").addEventListener("touchend", thisTouchEnd, true); 
document.getElementById("map_canvas").addEventListener("touchmove", thisTouchMove, true); 
+0

Uwaga: Wiem, że mógłbym po prostu dołączyć 'przeciągalny: false' w opcjach początkowych, ale funkcja initialize() jest funkcją ogólną, której używam również w innych mapach, które chcę przeciągnąć. 'map.setOptions' to sposób na dostosowanie każdej mapy po utworzeniu. – joshuahedlund

+1

Notatka dla osób korzystających z jQuery: musisz pobrać atrybut 'touches' z oryginalnego zdarzenia, a nie z zdarzenia opakowanego w jQuery. Na przykład: '$ (" # map_canvas "). On (" touchstart ", funkcja (e) {dragFlag = true; start = e.originalEvent.touches [0] .pageY;});' –

+0

rozwiązuje problem z przewijaniem pełna mapa strony na urządzeniu z Windows Phone 8.1, dziękuję! – Picard

Powiązane problemy