【问题标题】:Embed Google Maps on page without overriding iPhone scroll behavior在页面上嵌入谷歌地图而不覆盖 iPhone 滚动行为
【发布时间】:2011-09-23 21:08:57
【问题描述】:

我正在优化移动网站。我们有一个位置页面,其中包含有关位置的信息和通过 Google Maps API 绘制的位置地图。 (v2 - 我知道它已被弃用,但我没有证明升级的时间是合理的,“如果它没有损坏..”)我想使用单列布局,其中包含基本信息,然后是地图,然后是更多信息。

现在,当我用手指在 iPhone 上向下滚动移动页面时,一旦我到达地图,页面滚动就会被覆盖,地图开始平移。我向下滚动页面的唯一方法是将手指放在地图上方或下方,假设这样的空间可用。如果我禁用地图拖动,那么当我开始向下滚动并到达地图时,它不会平移,但页面也不会滚动。我想将地图视为可以滚动过去的静态图像,但仍允许缩放按钮并允许通过我编码的选择字段使用方向重绘地图,因此literal static image 不是解决方案。

我找到了this post that required similar functionality,但它使用的是 v3。我认为我需要做的就是“将触摸事件添加到地图容器”,但我不熟悉 javascript 的那部分,并且我在下面的内容不允许正常滚动。我是否需要在 v3 上咬紧牙关,还是在添加触摸事件时遇到错误,该错误具有简单的 javascript 更正来执行我想要的操作?

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);

我也尝试将map.addEventListener 替换为document.getElementById("map_canvas").addEventListenerdocument.addEventListener 无济于事。

【问题讨论】:

  • 地图位于 Google 托管的 iframe 中,除非 Google 允许您使用 JavaScript 切换,否则您可能不走运。 API v2 已被弃用,所以如果您发现使用版本 3 的东西可以工作,为什么不进行切换呢? API v3 具有更多功能并且更易于使用,恕我直言,无论如何。 (一个不需要更多的 API 密钥!)
  • 在发布之前我开始研究 v3。没有 API 密钥很好,但我们需要使用地理编码功能,它看起来确实需要 API 密钥,而且它的响应看起来比 v2 更复杂,我们还有一些其他页面也在使用它。基本上,我试图通过快速修复 v2 来避免为 v3 重新编码几个小时,但如果这不可能,我会放弃并进行明智的升级。
  • 我现在已升级到 v3,但无法让触摸事件正常工作。我正在仔细研究我的 javascript 是否有错误,但我无法让触摸事件响应任何内容。
  • 最好的办法是删除整个问题,然后为这个新问题开始一个新问题。

标签: javascript iphone mobile google-maps-api-3 google-maps-api-2


【解决方案1】:

我通过升级到 v3 解决了这个问题,然后在我使用上面链接的解决方案中的代码时检测到一个基本的 javascript 错误。关键是

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

用户一定是在给出的代码之外的某个地方设置了 events 变量,因为看起来匹配的赋值是针对触摸事件的,而 else 的赋值是针对按键事件的。但由于我没有 events 变量,因此默认分配错误。我只是将我的更改为start = e.touches[0].pageY(并且对 touchend 事件做了同样的事情),现在一切正常。

但是,我切换回 v2 以查看它是否可以与更正的 javascript 错误一起使用,但它没有。所以看起来我并没有浪费任何时间升级到 v3,既没有想出这个特定的解决方案,也没有为未来的兼容性做好准备。

总之,如果您想在移动页面上嵌入 Google 地图并能够滚动过去,您需要使用 API v3、禁用拖动并添加触摸事件。我还对我的代码进行了一些小的调整,在这里展示给任何可能在未来受益的人:

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);

【讨论】:

  • 注意:我知道我可以简单地将draggable: false 包含在初始选项中,但是initialize() 函数是一个通用函数,我也将它用于我想要拖动的其他地图。 map.setOptions 是一种在创建后自定义每个地图的方法。
  • 给使用 jQuery 的人的注意事项:您需要从原始事件中检索 touches 属性,而不是 jQuery 包装的事件。例如:$("#map_canvas").on("touchstart", function(e) { dragFlag = true; start = e.originalEvent.touches[0].pageY; });
  • 解决了在 Windows Phone 8.1 设备上滚动整页地图的问题,谢谢!
猜你喜欢
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-09
  • 1970-01-01
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
相关资源
最近更新 更多