【问题标题】:javascript for loop not executing function until end of loop, then iterating function n number of timesjavascript for循环直到循环结束才执行函数,然后迭代函数n次
【发布时间】:2013-05-08 16:04:19
【问题描述】:

我正在尝试从一个循环中加载一些带有谷歌地图图像的 div,该循环将一个添加到 document.get 的值。问题是 getLocation() 调用出现在循环的最后一次迭代中,但随后将循环迭代 n 次。

for(var i = 1; i < length; i++){
var longitude = 1.8612393999999999;
var latitude = 50.7263312;
document.getElementById("longInput").value = longitude;
document.getElementById("latInput").value = latitude;

var mapholder = "mapholderM"+i;
document.getElementById("mapholderValue").value = mapholder;
theMapholder=document.getElementById(mapholder);

getLocation();
}

getLocation() 为 lat 和 lon 变量使用 longInput 和 latInput 值,并将 Mapholder 作为放置目标 div 图像的位置。地图能够获取坐标,并且如下所述,在循环的最终或结束时还可以获取 theMapholder 值。

我认为这不是 getLocation() 的问题,以及我尝试使用它的方式。 通过在 getLocation() 调用中添加警报并查看屏幕上的元素,我知道 元素通过循环填充并更改,然后在发生这种情况后调用获取位置 n 次。然后 getLocation() 只获取在给元素值的迭代完成时设置的值。

在循环开始时添加一个警报,使循环循环 n 次,然后只执行一次 getLocation()。

总结一下: 一个接一个地循环和更改元素值。 一旦完成,就会调用 getLocation(),并使用相同的迭代次数。 getLocation() 现在只能访问元素的最终设置,因此只给一个 div 一个地图。

院长

更新: 很抱歉提供了不正确的信息:我的循环中的任何方法调用都会导致相同的行为:

function pulse(){
     $('#contentDiv').delay(200).fadeOut('slow').delay(50).fadeIn('slow');    
}

从我的循环中调用这个方法:

for(var i = 1; i < length; i++) {        
    var longitude = 1.8612393999999999;
    var latitude = 50.7263312;

    alert("end of loop");        
    pulse();
}

导致警报 n 次,然后执行脉冲?很抱歉造成混乱。

院长

更新: 谷歌地图脚本:

function getLocation()
  {
  if (navigator.geolocation)
    {
    navigator.geolocation.getCurrentPosition(showPosition,showError);
    }
  else{x.innerHTML="Geolocation is not supported by this browser.";}
  }

function showPosition(position)
  {
  alert($("#longInput").val()); */
  lat= $("#latInput").val();
  lon= $("#longInput").val();
  latlon=new google.maps.LatLng(lat, lon);
  mapholder=theMapholder;

  alert("getLocation " + theMapholder);

  var myOptions={
  center:latlon,zoom:14,
  mapTypeId:google.maps.MapTypeId.ROADMAP,
  mapTypeControl:false,
  navigationControlOptions:{style:google.maps.NavigationControlStyle.SMALL}
  };
  var map=new google.maps.Map(theMapholder,myOptions);
  var marker=new google.maps.Marker({position:latlon,map:map,title:"You are here!"});
  }

  function showError(error)
  {
  switch(error.code) 
    {
    case error.PERMISSION_DENIED:
      x.innerHTML="User denied the request for Geolocation."
      break;
    case error.POSITION_UNAVAILABLE:
      x.innerHTML="Location information is unavailable."
      break;
    case error.TIMEOUT:
      x.innerHTML="The request to get user location timed out."
      break;
    case error.UNKNOWN_ERROR:
      x.innerHTML="An unknown error occurred."
      break;
    }
  }
</script>

使用 showPosition 中的警报,我可以看到它仅在循环更新元素后被调用。

为什么 a 函数的行为是这样的,并且只有在循环执行完其他所有操作后才被调用?

【问题讨论】:

  • 请缩进您的代码。很难阅读。
  • 看看“getLocation()”函数会非常有帮助。
  • “延迟”、“淡出”等效果是异步。 “脉冲”功能将立即返回,但效果会随着时间的推移而持续。
  • 您不能以这种方式进行渐进更改(如“fadeIn”)。您可以将回调函数传递给这些动画,并从回调开始后续动画。
  • 没有办法在 for 循环中进行多个视觉更改,其中 UI 会在 for 循环的每次迭代后更新。您必须使用异步回调来实现它,例如使用 setTimeout

标签: javascript function for-loop


【解决方案1】:

正如任何人都知道的那样,阅读这篇文章有点令人困惑,可能是因为需要学习更多和 javascript,尽管正如您将在 cmets 中看到的那样,我有一些很好的建议可供学习。我如何解决这个问题:

getLocation() 正在迭代,在循环完成对所有其他代码的迭代之后。因此,作为一种技巧,当迭代 getLocation() 方法时,是时候更改该函数可以使用的元素值了:

  var y=1;
  var x=document.getElementById("demo");

  function getLocation()
  {
  if (navigator.geolocation)
    {
    navigator.geolocation.getCurrentPosition(showPosition,showError);
    }
  else{x.innerHTML="Geolocation is not supported by this browser.";}
  }

  function showPosition(position)
  {
    var longitude = -1.8612393999999999;
    var latitude = 50.7263312;

    document.getElementById("longInput").value = longitude;
    document.getElementById("latInput").value = latitude;

    var mapholder = "mapholderM"+y;
    document.getElementById("mapholderValue").value = mapholder;
    theMapholder=document.getElementById(mapholder);

    lat= $("#latInput").val();   
    lon= $("#longInput").val();
    latlon=new google.maps.LatLng(lat, lon);
    mapholder=theMapholder; 
    alert("getLocation " + theMapholder+y);
    y++;

    var myOptions={
      center:latlon,zoom:14,
      mapTypeId:google.maps.MapTypeId.ROADMAP,
      mapTypeControl:false,
      navigationControlOptions:{style:google.maps.NavigationControlStyle.SMALL}
    };

  var map=new google.maps.Map(theMapholder,myOptions);
  var marker=new google.maps.Marker({position:latlon,map:map,title:"You are here!"});
}

注意变量 y 的引入,每次调用该方法以在获取元素 id 中使用时,该变量的值都会增加。

【讨论】: