简体   繁体   中英

Uncaught TypeError: Cannot call method 'panTo' of undefined

I'm occasionally seeing a javascript error (Uncaught TypeError: Cannot call method 'panTo' of undefined) when loading my website. My website, for reference, is www.nolofo.com . What is supposed to happen when you load that page is to determine your location and move the map to that location. Sometimes this works just fine, other times it does not. I can't seem to figure out the pattern other than when it doesn't work I see this error message in the javascript log. Perhaps something is not being loaded in the correct order?

<script type="text/javascript">

// Check to see if this browser supports geolocation.
if (navigator.geolocation) {

    // This is the location marker that we will be using on the map. Let's store a reference to it here so that it can be updated in several places.
    var locationMarker = null;
    var myLat = null;
    var myLng = null;

    // Get the location of the user's browser using the native geolocation service.
    navigator.geolocation.getCurrentPosition(
        function (position) {

            // Check to see if there is already a location. There is a bug in FireFox where this gets invoked more than once with a cached result.
            if (locationMarker){
                return;
            }

            // Log that this is the initial position.
            console.log( "Initial Position Found" );

            // Assign coordinates to global variables
            myLat = position.coords.latitude;
            myLng = position.coords.longitude;

            moveToLocation(myLat, myLng);

        }

    );

}

// Start the Google Maps implementation
var map;
var markersArray = [];
function initialize() {
    var mapOptions = {
        zoom: 13,
        center: new google.maps.LatLng(40.760779, -111.891047),
        mapTypeId: google.maps.MapTypeId.TERRAIN,
        scaleControl: true
    };
    map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

    // Add all recent listing markers to map
    <?php
        foreach ($coordinateArray as $Key => $Value) {

        $listingQuery = mysql_query("
            SELECT
                Listings.Lat,
                Listings.Lng,
                Listings.Title,
                Listings.Type
            FROM
                Listings
            WHERE
                Listings.ID='$Key'
        ");
        if (!$listingQuery) {
            die('<p>Error executing query (2) with database!<br />'.
            'Error: ' . mysql_error() . '</p>');
        }
        $listingArray = mysql_fetch_array($listingQuery);
            $ListingLat = $listingArray["Lat"];
            $ListingLng = $listingArray["Lng"];
            $ListingTitle = addslashes($listingArray["Title"]);
            $ListingType = $listingArray["Type"];

        $ListingLatLng = $ListingLat . ", " . $ListingLng;

    ?>
    // Marker
    var myLatLng = new google.maps.LatLng(<?=$ListingLatLng?>);
    var marker<?=$Key?> = new google.maps.Marker({
        position: myLatLng,
        map: map,
        title: ""
    });
    iconFile = 'http://maps.google.com/mapfiles/ms/icons/<?=$Value?>-dot.png'; 
    marker<?=$Key?>.setIcon(iconFile);

    // Info Window
    var infowindow<?=$Key?> = new google.maps.InfoWindow({
        content: '<b><?=$ListingType?></b><br /><a href="/listing.php?ID=<?=$Key?>"><?=$ListingTitle?></a>'
    });
    google.maps.event.addListener(marker<?=$Key?>, 'click', function() {
        infowindow<?=$Key?>.open(map, marker<?=$Key?>);
    });
    <?php } ?>

    // Add a click event handler to the map object
    google.maps.event.addListener(map, "click", function(event) {
        // Place a marker
        placeMarker(event.latLng, event.latLng.lat(), event.latLng.lng());

        // Display the lat/lng in your form's lat/lng fields
        //document.getElementById("lat").value = event.latLng.lat();
        //document.getElementById("lng").value = event.latLng.lng();
    });

    // Add a click event handler to the marker object
    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent("Your content here");
        infowindow.open(map, this);
    });

}

function placeMarker(location, lat, lng) {
    // Remove all markers if there are any
    deleteOverlays();

    var marker = new google.maps.Marker({
        position: location, 
        map: map
    });

    // Add marker in markers array
    markersArray.push(marker);

    var contentString = '<a href="/post/start.php?Lat=' + lat + '&Lng=' + lng + '">New Listing</a>';

    var infowindow = new google.maps.InfoWindow({
        content: contentString
    });

    infowindow.open(map,marker);

    google.maps.event.addListener(infowindow, "closeclick", function() {
        deleteOverlays(); // removes the marker
    });

    //map.setCenter(location);
}

// Deletes all markers in the array by removing references to them
function deleteOverlays() {
    if (markersArray) {
        for (i in markersArray) {
            markersArray[i].setMap(null);
        }
        markersArray.length = 0;
    }
}

function moveToLocation(lat, lng) {
    var center = new google.maps.LatLng(lat, lng);
    map.panTo(center);
}

// The function to trigger the marker click, 'id' is the reference index to the 'markers' array.
function linkClick(id){
    google.maps.event.trigger(markersArray[id], 'click');
}

google.maps.event.addDomListener(window, 'load', initialize);

Most likely it's because you're trying to pan the map before the map has been loaded. You run that initial geolocation script as soon as the page is loaded. Sounds like sometimes getCurrentPosition() is faster than the map load, sometimes it's not.

What you can do is run your geolocation stuff after map has been loaded. The very last line in your script is an event listener for when the map has been loaded - you can use it for other bits too.

Wrap the whole first part in a function:

function setupGeoLocator() {
    // Check to see if this browser supports geolocation.
    if (navigator.geolocation) {

        // This is the location marker that we will be using on the map. Let's store a reference to it here so that it can be updated in several places.
        var locationMarker = null;
        var myLat = null;
        var myLng = null;

        // Get the location of the user's browser using the native geolocation service.
        navigator.geolocation.getCurrentPosition(
            function (position) {

                // Check to see if there is already a location. There is a bug in FireFox where this gets invoked more than once with a cached result.
                if (locationMarker){
                    return;
                }

                // Log that this is the initial position.
                console.log( "Initial Position Found" );

                // Assign coordinates to global variables
                myLat = position.coords.latitude;
                myLng = position.coords.longitude;

                moveToLocation(myLat, myLng);

            }

        );

    }
}

And then call it when the 'load' event fires on the map.

google.maps.event.addDomListener(window, 'load', initialize);
google.maps.event.addDomListener(window, 'load', setupGeoLocator);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM