Ошибка области действия JavaScript - PullRequest
1 голос
/ 12 ноября 2008

В настоящее время я работаю над проектом Google Maps и внедряю функцию поиска. В своей функции поиска я пытаюсь разместить в боковом списке контент, который поисковики, которые были только что добавлены на карту, соответствуют каждому залу. Однако при сборке этой строки я столкнулся с проблемой, когда моя переменная side_bar_html не будет выводиться, если я сначала не оповестю данные.

Вот моя функция searchMap. Переменная объявлена ​​так: var side_bar_html = "";

function searchMap(term, map) {

closeSearch();  

searchCount = 0;
searchMarkers = [];

var request = GXmlHttp.create();

    request.open("GET", "admin/search.php?s=" + term, true);

    request.onreadystatechange = function() {

    if (request.readyState == 4) {

        var xmlDoc = GXml.parse(request.responseText);
        var points = xmlDoc.documentElement.getElementsByTagName("point");

        var polygonsToShow = [];
        for (var i = 0; i < points.length; i++) {                                   
            var lat = parseFloat(points[i].getAttribute("lat"));
            var lng = parseFloat(points[i].getAttribute("lng"));
            var pid = points[i].getAttribute("id");
            for(var j = 0; j < polygons.length; j++) {
                if(polygons[j].vt_bid == pid) {
                    polygonsToShow.push(j);
                }
            }
            var point = new GLatLng(lat,lng);           
            var pname = points[i].getAttribute("name");
            var curMarker = createSearchMarker(point, pid, pname,getLetter(i));                 
            map.addOverlay(curMarker);
        }
        //olays.buildings.checked = false; : Figure out some way to uncheck the buildings overlay checkbox?
        for(var k = 0; k < polygons.length; k++) {
            polygons[k].hide();
        }

        for(var l = 0; l < polygonsToShow.length; l++){ 
            polygons[polygonsToShow[l]].show();
        }
    }
}

request.send(null);
alert(side_bar_html); //side_bar_html will be empty unless I alert the variable


searchResults = new HtmlControl('<div style="background-color:white; border:solid 1px grey; padding:2ex; overflow:auto; width:125px; margin:1px;  font-size:14px;"><img align="right" style="cursor: pointer;" src="http://www.thebort.com/maps/images/close.gif" onclick="closeSearch()"><strong>Search</strong><br/>' + side_bar_html + '</div>', {selectable:true});
map.addControl(searchResults, new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(20, 70)));

}

И функция для создания поискового маркера:

function createSearchMarker(point, id, pname, letIcon) {
    var marker = new GMarker(point,letIcon);
    GEvent.addListener(marker, "click", function() {         
        marker.openInfoWindowHtml('<a href="#" onclick=\'tb_show("' + pname + '","admin/get_info.php?b=' + id + '&KeepThis=true&TB_iframe=true&height=400&width=600",false); return false;\'>' + pname + '</a>');

     });

side_bar_html = side_bar_html + '<a href="javascript:clickSearch(' + searchCount + ')">' + String.fromCharCode("A".charCodeAt(0) + searchCount) + ': ' + pname + '</a><br>';
marker.vt_id = id;
    searchMarkers.push(marker);
searchCount++;

    return marker;
 }

Я бы хотел, чтобы сейчас выдержка кода для этого проекта была минимальной, поэтому, если что-то нужно объяснить, пожалуйста, дайте мне знать. Спасибо!

Ответы [ 2 ]

4 голосов
/ 12 ноября 2008

Итак, я понимаю вашу проблему в том, что side_bar_html устанавливается во время вызова функции onreadystatechange, но вы не увидите, что она установлена, пока не предупредите ее.

Вот что, вероятно, происходит: запрос Ajax занимает некоторое время. Когда вы вызываете req.send(null), это вызывает запрос, но ваша функция onreadystatechange не будет вызываться до тех пор, пока ваш веб-браузер не выполнит запрос и не получит ответ.

Поэтому, когда вы сразу же попытаетесь использовать значение side_bar_html, оно не сработает, потому что ответ еще не вернулся. Однако, когда вы предупреждаете значение, время, необходимое для его выдачи, дает браузеру время для получения ответа и соответствующей установки значения side_bar_html.

Ваша основная проблема в том, что Ajax является асинхронным (то есть, откуда исходит A), и вы пытаетесь использовать его синхронно (это означает, что вы предполагаете, что вещи всегда будут происходить в определенном порядке). Лучше всего поместить код, который использует side_bar_html, в вашу функцию onreadystatechange, чтобы он не использовался до того, как он будет установлен.

0 голосов
/ 12 ноября 2008

добавьте приведенный ниже код в конец вашей функции onreadystatechange (в операторе if, проверяющем значение 4). например:

request.onreadystatechange = function() {

if (request.readyState == 4) {

    var xmlDoc = GXml.parse(request.responseText);
            var points = xmlDoc.documentElement.getElementsByTagName("point");

            var polygonsToShow = [];
            for (var i = 0; i < points.length; i++) {                                                       
                    var lat = parseFloat(points[i].getAttribute("lat"));
                    var lng = parseFloat(points[i].getAttribute("lng"));
                    var pid = points[i].getAttribute("id");
                    for(var j = 0; j < polygons.length; j++) {
                            if(polygons[j].vt_bid == pid) {
                                    polygonsToShow.push(j);
                            }
                    }
                    var point = new GLatLng(lat,lng);                       
                    var pname = points[i].getAttribute("name");
                    var curMarker = createSearchMarker(point, pid, pname,getLetter(i));                             
                    map.addOverlay(curMarker);
            }
            //olays.buildings.checked = false; : Figure out some way to uncheck the buildings overlay checkbox?
            for(var k = 0; k < polygons.length; k++) {
                    polygons[k].hide();
            }

            for(var l = 0; l < polygonsToShow.length; l++){ 
                    polygons[polygonsToShow[l]].show();
            }

            searchResults = new HtmlControl('<div style="background-color:white; border:solid 1px grey; padding:2ex; overflow:auto; width:125px; margin:1px;  font-size:14px;"><img align="right" style="cursor: pointer;" src="http://www.thebort.com/maps/images/close.gif" onclick="closeSearch()"><strong>Search</strong><br/>' + side_bar_html + '</div>', {selectable:true});
            map.addControl(searchResults, new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(20, 70)));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...