谷歌地图API BackBoneJS无法读取属性“offsetWidth”空的 [英] Google Map API BackBoneJS Cannot read property 'offsetWidth' of null

查看:188
本文介绍了谷歌地图API BackBoneJS无法读取属性“offsetWidth”空的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经历过许多计算器/谷歌群体,因为我可以想像试图找出这家伙出来。

我使用BackboneJS渲染图,有一个起始位置和结束位置。在新的一页/页面刷新,我没有得到这个错误,地图之类的东西做工精细,因为我使用jQuery的$(窗口).load(.....)功能;然而,当我动态地呈现我的看法,我得到这个错误,我相信,因为DOM没有加载DIV尚未(通过document.getElementById失败)。我曾尝试比$(窗口).load(其他)不同的方法都态度,但我不能得到任何这既适用于用例(新鲜页面加载 - BackboneJS查看加载)。试图调用该函数之后的模板不工作,要么。

任何帮助将是AP preciated。

罗伯特

查看:

  App.Views.MapShow = Backbone.View.extend({
      初始化:功能(){
        _.bindAll(这一点,'渲染');
        VAR自我=这一点;
        $(窗口).load(函数(){
          self.renderMap();
        });
      },      渲染:功能(){
        this.renderTemplate();
      },      renderTemplate:功能(){
        这$ el.html(JST ['路径/要/显示/文件'());
      },      renderMap:功能(){
        从= this.model.get VAR('location_from');
        VAR为= this.model.get('location_to');
        VAR地理codeR =新google.maps.Geo codeR();
        VAR地图=新google.maps.Map(的document.getElementById('mapCanvas'){
          mapTypeId设为:google.maps.MapTypeId.ROADMAP
        });
        VAR为DirectionsService =新google.maps.DirectionsService();
        VAR directionsDisplay =新google.maps.DirectionsRenderer();        directionsDisplay.setMap(地图);        VAR请求= {
          产地:从,
          目标:到,
          travelMode:google.maps.DirectionsTravelMode.DRIVING
        };        directionsService.route(要求,功能(响应状态){
          如果(状态== google.maps.DirectionsStatus.OK){
            directionsDisplay.setDirections(响应);
          }
        });
      }
    });

HTML

 < D​​IV CLASS =地图ID =mapCanvas>< / DIV>


解决方案

我猜你的问题是, #mapCanvas 不在DOM,直到后尝试访问它所以这个:

 的document.getElementById('mapCanvas')

会给你一个没用的。您需要等到 #mapCanvas 在使用它之前的DOM;你不能做这样的事情之一:

  map_canvas提供= $这个el.find('#mapCanvas')[0];

这会给你一个有效的身份证件,但你会混淆了谷歌地图的功能,因为它不会有一个大小,这样的地图将呈现奇怪。这让你回等待一切是在DOM绑定您的谷歌地图的东西了。

解决此问题的方法是使用 的setTimeout 为零延时

  VAR _this =这一点;
的setTimeout(函数(){_this.renderMap()},0);

这看起来有点怪它做的工作,这一招基本上转储你的 renderMap 调用到浏览器的工作队列,它会避开运行它一旦你回来控制浏览器。

您也可以使用 _推迟


  

延迟 _。推迟(函数,[*参数])


  
  

推迟调用的功能,直到当前调用堆栈已被清除,类似于使用的setTimeout 与0有用的块中进行昂贵的计算或HTML渲染没有延迟从更新阻塞UI线程。


,因为它让你的意图明确,这可能是一个更好的选择。

I've been through as many StackOverflow/google groups as I can imagine trying to figure this guy out.

I'm using BackboneJS to render a map that has a start location and an end location. On a fresh page/page refresh, I don't get this error, and the map and stuff work fine, for I am using jQuery's $(window).load(.....) function; however, when I dynamically render my View, I get this error-I believe-because the DOM hasn't loaded the DIV yet (failing with document.getElementById). I have tried all manner of different methods other than the $(window).load(), but I can't get anything which works for both use cases (fresh page load -- BackboneJS view loading). Trying to call the function right after the template doesn't work, either.

Any help would be appreciated.

Robert

View:

    App.Views.MapShow = Backbone.View.extend({
      initialize: function() {
        _.bindAll(this, 'render');
        var self = this;
        $(window).load(function() {
          self.renderMap();
        });
      },

      render: function() {
        this.renderTemplate();
      },

      renderTemplate: function() {
        this.$el.html(JST['path/to/show/file']());
      },

      renderMap: function() {
        var from     = this.model.get('location_from');
        var to       = this.model.get('location_to');
        var geocoder = new google.maps.Geocoder();
        var map      = new google.maps.Map(document.getElementById('mapCanvas'), {
          mapTypeId: google.maps.MapTypeId.ROADMAP
        });
        var directionsService = new google.maps.DirectionsService();
        var directionsDisplay = new google.maps.DirectionsRenderer();

        directionsDisplay.setMap(map);

        var request = {
          origin: from,
          destination: to,
          travelMode: google.maps.DirectionsTravelMode.DRIVING
        };

        directionsService.route(request, function(response, status) {
          if (status == google.maps.DirectionsStatus.OK) {
            directionsDisplay.setDirections(response);
          }
        });
      }
    });

HTML:

    <div class="map" id="mapCanvas"></div>

解决方案

I'd guess that your problem is that #mapCanvas isn't in the DOM until after you try to access it so this:

document.getElementById('mapCanvas')

will give you a useless null. You need to wait until #mapCanvas is in the DOM before using it; you can't do something like this either:

map_canvas = this.$el.find('#mapCanvas')[0];

That will give you a valid ID but you'll confuse the Google Maps functions because it won't have a size so the map will be rendered oddly. This puts you back to waiting for everything to be in the DOM before binding your Google Maps stuff.

One way around this is to use setTimeout with a delay of zero:

var _this = this;
setTimeout(function() { _this.renderMap() }, 0);

This looks strange bit it does work, this trick basically dumps your renderMap call into the browser's work queue and it'll get around to running it once you've returned control to the browser.

You can also use _.defer:

defer _.defer(function, [*arguments])

Defers invoking the function until the current call stack has cleared, similar to using setTimeout with a delay of 0. Useful for performing expensive computations or HTML rendering in chunks without blocking the UI thread from updating.

This might be a better choice as it makes your intent explicit.

这篇关于谷歌地图API BackBoneJS无法读取属性“offsetWidth”空的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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