如何为数组中的每个元素运行函数

时间:2019-04-18 16:54:55

标签: javascript jquery loops

我想根据距离显示div。为此,我要获取用户的位置以及div应该出现的位置的坐标,并且我成功地做到了这一点。我现在的问题是,我希望在不同的地方都可以使用它,所以我需要找到一种循环的方法,并不断检查人在哪里,看看它是否靠近我的坐标距离。

-获取人的位置

if (navigator.geolocation){
    navigator.geolocation.watchPosition(showPosition)
}

-显示div的功能

function showPosition(position){

  let locationLatitude = []
  let locationsLongitude = []

  //AJAX CALL TO GET THE POSITION OF THE PLACES AND PUSHING THEM TO THE ARRAYS
  let success = function(res){
    let locations = res.locations

    for (var i=0; i<locations.length; i++){
      locationLatitude.push(locations[i]['place_latitude'])
      locationsLongitude.push(locations[i]['place_longitude'])
    }
  }

   $.ajax({
      type: 'GET',
      url: '/api/locations',
      crossDomain: true,
      dataType: 'json',
      async: false,
      success : success,
  });

  // LOOP TO GET ALL COORDIANTES FROM PLACES (LAT,LONG)
  var locationLatitudeLength = locationLatitude.length
  var locationsLongitudeLength = locationsLongitude.length
  let startPosLat
  let startPosLong

  for(var i=0; i<locationLatitudeLength; i++){

    for(var j=0; j<locationsLongitudeLength; j++){
      startPosLat = locationLatitude[i]
      startPosLong = locationsLongitude[j]

      userlocationLatitude = position.coords.latitude
      userlocationLongitude = position.coords.longitude

     //PASS VALUES OF COORDINATES TO THE FUNCTION
     let distance = calculateDistance(startPosLat, startPosLong, userlocationLatitude, userlocationLongitude)

      }

  }

   if(distance < .05){
      $('.div-image').attr('src', 'pic2.jpg')
   }else if(distance > .05){
      $('.div-image').attr('src', 'pic.jpg')
   }


    //function to calculate the distance between two points of coordinates 
    function calculateDistance(lat1, lon1, lat2, lon2) {
        var R = 6371; // km
        var dLat = (lat2-lat1).toRad();
        var dLon = (lon2-lon1).toRad();
        var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
                Math.sin(dLon/2) * Math.sin(dLon/2);
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        var d = R * c;
        return d;
    }
      Number.prototype.toRad = function() {
        return this * Math.PI / 180;
    }
}

问题是它无法识别来自循环的坐标。

任何人都对如何使函数在循环上的每个坐标上运行以检查我是否在那里提出建议。

3 个答案:

答案 0 :(得分:3)

看来,遍历坐标的双循环并没有等待ajax的响应(我假设在处理之前需要所有坐标)。由于ajax调用是异步的,因此在服务器响应之前不会填充位置。但是,遍历locations数组的循环将在向服务器发出初始请求后立即开始执行,最重要的是,在填充位置之前。

尝试将大部分功能移至成功功能。

function showPosition(position){

  let locationLatitude = []
  let locationsLongitude = []

  //AJAX CALL TO GET THE POSITION OF THE PLACES AND PUSHING THEM TO THE ARRAYS
  let success = function(res){
    let locations = res.locations

    for (var i=0; i<locations.length; i++){
      locationLatitude.push(locations[i]['place_latitude'])
      locationsLongitude.push(locations[i]['place_longitude'])
    }

    // LOOP TO GET ALL COORDIANTES FROM PLACES (LAT,LONG)
    var locationLatitudeLength = locationLatitude.length
    var locationsLongitudeLength = locationsLongitude.length
    let startPosLat
    let startPosLong

    for(var i=0; i<locationLatitudeLength; i++){

      for(var j=0; j<locationsLongitudeLength; j++){
        startPosLat = locationLatitude[i]
        startPosLong = locationsLongitude[j]

        userlocationLatitude = position.coords.latitude
        userlocationLongitude = position.coords.longitude

        //PASS VALUES OF COORDINATES TO THE FUNCTION
        let distance = calculateDistance(startPosLat, startPosLong, userlocationLatitude, userlocationLongitude)
      }
    }

    if(distance < .05){
        $('.div-image').attr('src', 'pic2.jpg')
    }else if(distance > .05){
        $('.div-image').attr('src', 'pic.jpg')
    }
  }

   $.ajax({
      type: 'GET',
      url: '/api/locations',
      crossDomain: true,
      dataType: 'json',
      async: false,
      success : success,
  });

  //function to calculate the distance between two points of coordinates 
  function calculateDistance(lat1, lon1, lat2, lon2) {
      var R = 6371; // km
      var dLat = (lat2-lat1).toRad();
      var dLon = (lon2-lon1).toRad();
      var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
              Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
              Math.sin(dLon/2) * Math.sin(dLon/2);
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      var d = R * c;
      return d;
  }

  Number.prototype.toRad = function() {
    return this * Math.PI / 180;
  }
}```

答案 1 :(得分:1)

我首先建议使用数组数组存储坐标,以便您的纬度和经度彼此接近。我已经给出了一些循环的基本示例,假设您定义了checkFunction来处理坐标检查。

您可以使用香草JS这样循环:

for (var i in myArray) {
   checkFunction(myArray[i]);
}

或者您可以使用JQuery这样循环:

$(myArray).each(function(index, value) {
    checkFunction(value);
});

答案 2 :(得分:1)

我认为您的算法可以简化很多。特别是,将纬度和经度分成单独的数组,然后在以后使用嵌套的for循环使它们重新团聚似乎是不必要的。这是跳过这些步骤的建议。

请注意,这是完全未经测试的,但它可能会让您顺利进行。

要注意的其他事情是可能使用for...of而不是传统的for循环,在声明它的相同范围内使用distance,并为以下情况做好准备: distance == .05

function showPosition(position){
  const userlocationLatitude = position.coords.latitude;
  const userlocationLongitude = position.coords.longitude;
  let success = function(res){
    for(let location of res.locations){
      let startPosLat = location['place_latitude'],
          startPosLng = location['place_longitude'],
          distance = calculateDistance(startPosLat, startPosLong, userlocationLatitude, userlocationLongitude);
      if(distance < .05){ $('.div-image').attr('src', 'pic2.jpg'); }
      else{ $('.div-image').attr('src', 'pic.jpg'); }  
    }
  }
  $.ajax({ type: 'GET', url: '/api/locations', crossDomain: true, dataType: 'json', async: false, success : success });

  //function to calculate the distance between two points of coordinates 
  function calculateDistance(lat1, lon1, lat2, lon2) {
      var R = 6371, dLat = (lat2-lat1).toRad(), dLon = (lon2-lon1).toRad(),
          a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * Math.sin(dLon/2) * Math.sin(dLon/2),
          c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      return R * c;
  }
  Number.prototype.toRad = function() { return this * Math.PI / 180; }
}