Странность цикла Javascript - не остановится, только - PullRequest
0 голосов
/ 12 мая 2011

Я довольно новичок в jQuery и JavaScript, поэтому прости меня, если я пропускаю что-то очень очевидное.

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

Тем не менее, происходит то, что цикл никогда не заканчивается и кажется, что он непрерывно проходит по последнему элементу в массиве.

Вот мой код. включая некоторые из различных, которые я пробовал в комментариях:

    var maps;
    var isInitialView;
    $(document).ready(function () {



    //$.getJSON("/Services/Maps.svc/GetMaps", callback);

    $.ajax({
        url: "/Services/Maps.svc/GetMaps",
        dataType: 'json',
        async: false,
        success: callback
    });


    function callback(data) {
        console.log("inside callback");
        maps = data;
        isInitialView = true;
        rotateMapDetails();
    };


    $.ajaxSetup({ cache: false, async: false });

    //    $.getJSON("/Services/Maps.svc/GetMaps",
    //      function (data) {
    //          isInitialView = true;
    //          maps = data;
    //          //          for (var map in maps.d) {
    //          //              alert(map.MapName);
    //          //              $('#accordion').delay(delay).fadeIn(400, populateMapDetails(map)).fadeOut(400);
    //          //          }
    //          //          //rotateMapDetails();
    //          //          $.each(maps.d, function (key, map) {
    //          //              var delay = 1000;
    //          //              //alert("inside getJson loop, and mapName is :" + map.MapName);
    //          //              //$('#accordion').delay(delay).fadeIn(400, populateMapDetails(map)).fadeOut(400);
    //          //              //              sleep(delay);
    //          //              setInterval(function () {
    //          //                  populateMapDetails(map);
    //          //              }, 5000);
    //          //              //populateMapDetails(map);
    //          //$('#accordion').fadeOut(400);
    //          //              sleep(delay);
    //          // });
    //          //rotateMapDetails();
    //          console.log("inside getJson");
    //      }); 

    $('#accordion').load(function () {
        alert("accordion loaded");
        rotateMapDetails();
    });

    function rotateMapDetails() {
        var size = $(maps.d).length;
        console.log("maps.d has " + size + " elements");


        var delay = 4000;

                for (var map in maps.d) {
                    console.log("inside for loop");
                    console.log(maps.d[map]);
                    setInterval(function () {
                        populateMapDetails(maps.d[map]);
                                      }, delay);
                }



     //                for (var i=0;i<=size;i++)
      //                    {
      //                        setInterval(function () {
      //                            console.log(maps.d);
      //                            console.log(maps.d[i]);
      //                                     populateMapDetails(maps.d[i]);
      //                                 }, delay);
      //                    };



        //        $(maps.d).each(function (map) {
        //            if (isInitialView) {
        //                //var map = $(this);
        //                var delay = 4000;
        //                setInterval(function () {
        //                    console.log("inside rotateMapDetails and map is " + map.MapName);
        //                    populateMapDetails(map);
        //                }, delay);
        //            }
        //            else { return (false); };
        //            isInitialView = false;
        //            return (false);
        //        });
    };


    $('.ic_container').click(function () {
        $('#accordion').fadeIn(400);
        var mapName = jQuery("img", this).attr("alt")
        isInitialView = false;

        $.each(maps.d, function (key, map) {
            if (map.MapName === mapName) {

                populateMapDetails(map);
            }
        });
        var id = $(this).attr("id");
    });

    //populate side bar with map details
    function populateMapDetails(map) {
        console.log("populating mapDetails for " + map.MapName);

        //$('#accordion').delay(delay).fadeIn(400);
        $("#MapName").html(map.MapName);
        $("#Description").html(map.Description);
        $("#DirectLinklink").attr("href", map.MapUrl);
        var imgSrc = map.MapName;
        var src = imgSrc.replace(/\s/g, ""); //remove white space
        $("#detailImg").attr("src", "Images/MapThumbs/" + src + ".png");
        $("#LaunchLink").attr("href", map.MapUrl);
        $("#txtEmbed").val(map.EmbedLink);

        //alert(map.MapName);
        //$('#accordion').delay(delay).fadeOut(400);

        //setInterval(function () { console.log("inside populateMapDetails"); }, delay);

    };





   });

Спасибо за вашу помощь.

Ответы [ 3 ]

0 голосов
/ 12 мая 2011
   setInterval(function () {
      populateMapDetails(maps.d[map]);
         }, delay);

Вы имели в виду setTimeout () ?

0 голосов
/ 29 апреля 2013

Я считаю, что проблема в переменной map в цикле for. В отличие от многих других C-подобных языков, переменные в JavaScript ограничиваются функциями, а не блоками. Это означает, что переменная map является общей для всех замыканий, созданных в цикле. Когда цикл заканчивается, переменная карты указывает на последний индекс, и все обратные вызовы будут использовать этот последний индекс.

Вы можете создать функцию и сразу запустить ее, чтобы закрыть переменную карты следующим образом:

setInterval((function(map) {
    return function() {
        populateMapDetails(maps.d[map]);
    };
})(map), delay);
0 голосов
/ 12 мая 2011

Мне кажется, проблема в следующей строке:

 setInterval(function () {
                populateMapDetails(maps.d[map]);
                              }, delay);

То, что вы говорите, это выполнение функции populateMadDetails каждые несколько секунд.Таким образом, он будет делать это для каждого элемента вашей карты.это то, что вы хотите сделать?

В своем вопросе вы сказали, что хотите:

load a json file, then for each item in the json array, display its

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

Так что в этом случае вы хотите сделать что-то вроде:

populateMapDetails(maps.d[map])
setTimeout(..., delay);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...