2012-06-09 5 views
1

jquery mobile에 목록이 있습니다. 가장 가까운 주에 근거하여 목록을 작성하는 코드를 추가했습니다. 왠지 내 논리가 작동하지 않습니다. 어떤 아이디어? 또한 스크롤 할 때 목록이 매우 느립니다.지리적 위치 기반 목록 정렬

확인이 아웃 링크를 왼쪽 상단에 가장 가까운 위치 찾기 버튼을 클릭

http://www.jm.bugs3.com/gl/state.html

<script> 
function findMe(){ 

    if (navigator.geolocation !=undefined){ 
     navigator.geolocation.watchPosition(onFound, handleError); 
    } 
} 
function onFound(position){ 
    var userLat = position.coords.latitude; 
    var userLong = position.coords.longitude; 
    $('ul li').each(function (index){ 
     var locationLat = $(this).find('.lat').html(); 
     var locationLong = $(this).find('.long').html(); 
     var distance = getDistance(userLat, locationLat, userLong, locationLong); 
     $(this).data("distance", distance); 
    }) 

    reOrder(); 
} 



function handleError(error){ 
    alert ("Could not find location"); 
} 

function reOrder(){ 
    $('ul li').sort(sortAlpha).appendTo('ul'); 
} 

function sortAlpha(a, b){ 
    return $(a).data('distance') > $(b).data('distance') ? 1 : -1; //if True or false 1 or -1 
}; 
//Calculate the shortest distance based on lat and long 
function getDistance(lat1, lat2, lon1, lon2){ 
    var R = 6371; //KM 
    var d = Math.acos(Math.sin(lat1) * Math.sin(lat2) + 
      Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1)) * R 
     return d  
}; 

// 여기에 위도와 경도 좌표와 함께 목록에 대한 코드는

<div data-role="content"> 
     <ul data-role="listview" data-inset="true"> 
      <li> 
       <a href="#page2" data-transition="slide" >Alabama</a> 
       <div class="lat" style="visibility:hidden">31.375626</div> 
       <div class="long" style="visibility:hidden">-86.299592</div> 
      </li> 
      <li> 
       <a href="#page3" data-transition="slide">Alaska</a> 
       <div class="lat" style="visibility:hidden">60.216736</div> 
       <div class="long" style="visibility:hidden">-149.882995</div> 
      </li> 
      <li> 
       <a href="#page4" data-transition="slide">Arizona</a> 
       <div class="lat" style="visibility:hidden">32.447659</div> 
       <div class="long" style="visibility:hidden">-112.134568</div> 
      </li> 
      <li> 
       <a href="#page5" data-transition="slide" >Arkansas</a> 
       <div class="lat" style="visibility:hidden">33.678252</div> 
       <div class="long" style="visibility:hidden">-92.340846</div> 
      </li> 
      <li> 
       <a href="#page6" data-transition="slide" >Boston</a> 
       <div class="lat" style="visibility:hidden">41.358431</div> 
       <div class="long" style="visibility:hidden">-71.059773</div> 
      </li> 
+0

링크가 작동하지 않습니다. 여기 열지 마. – nunespascal

답변

0

허쉬,

은 "... 나는에서 오전 가까운 상태에 따라"다음과 같은 이유로 해석하기 어려운 태드입니다 : 간단한에서

  • , "가장 가까운 주에 있음 "상태"에 있음 "
  • "주에 가장 가까운 지리적 중심지 "는"내가 속한 주 "가 아닐 수도 있습니다 (예 : 플로리다 주 서부 끝에있는 경우). 판 손잡이, 그 다음 "가장 가까운 주"는 알라바마, 플로리다가 아닙니다)
  • 상태가 좋지 않을 수 있습니다 (예 : 나는 바다에있다.)
이러한 어려움에도 불구하고

및 자신의 코드가 제대로 적절한 의미를 반영 신뢰하고, 시작점으로 @ ddotsenko의 대답에서 작업 한 후 다음과 같은 개선이 이루어 될 수 있습니다

  • 진정한 정렬 작업을 수행 할 수 있습니다 <li> 참조를 객체가 아닌 배열에 거리 (반올림)로 인덱싱하여 피할 수 있습니다. 이것은 올바른 순서로 희소 배열을 제공합니다.
  • <li> 요소는 각 <ul> 요소가 필요하지 않도록 원래 <ul> 범위 내에서 재정렬 할 수 있습니다. 다음과 같이 될 것이다 내장이 점, ddotsenko의 코드의 수정 된 버전을 촬영

:

function onFound(position) { 
    var userLat = position.coords.latitude, 
     userLong = position.coords.longitude, 
     arr = [], 
     $ul = $("ul");//a more specific selector would be good 
    $ul.find('li').each(function (index) { 
     var $this = $(this), 
      lat = Number($this.data("latitude")), 
      lng = Number($this.data('longitude')), 
      dist = Math.round(getDistance(userLat, lat, userLong, lng)); 
     arr[dist] = this; 
    }); 
    //At this point, arr is a sparse array of li elements indexed by distance, hence in distance order. 
    for(var item in arr) { 
     //Ref: "Iterating over sparse arrays", //http://hexmen.com/blog/2006/12/iterating-over-sparse-arrays/ 
     if (String(item >>> 0) == item && item >>> 0 != 0xffffffff) { 
      $ul.append(item); 
     } 
    }; 
} 

이 상당히 빨리해야합니다.

느린 스크롤링과 관련하여 DOM의 요소를 줄이면 더 나을 것입니다. ddotsenko의 코드의 javasctipt은 다음과 같은 형식의 <li>s을 나타냅니다 숨겨진 된 div보다 더해야

<li data-latitude="31.375626" data-longitude="-86.299592"> 
    <a href="#page2" data-transition="slide" >Alabama</a> 
</li> 

이 데이터를 보유 할 수 있습니다.

모든 위도/경도 쌍 따라서 DOM에서 느린 구출을 피하고, 자바 스크립트에 하드 코딩해야하는 것입니다 더 나은, 예를 들면 :

var stateLocations = { 
    "Alabama": {lat: 31.375626, lng: -86.299592}, 
    "Alaska": {lat: 60.216736, lng: -149.882995}, 
    "Arizona": {lat: 32.447659, lng: -112.134568}, 
    "Arkansas": {lat: 33.678252, lng: -92.340846}, 
    ... 
}; 

그런 다음 그에 따라 찾아보십시오.

그런데 보스턴은 도시가 아니라 주입니다. 미국은 "B"로 시작하지 않습니다.

1

자바 스크립트의 정렬은 O (n)입니다. 즉, 그것은 한 번 이상 각 요소를 건 드린다. 이것은 당신이 .DATA이 (같은 ELEM에 걸쳐 여러 번 호출 할 의미 당신은 브라우저마다 다시 그리기 트리거링이 그것을 여러 번 이동합니다.

는 정렬의 "거리"배열의 요소를 정렬하지 마십시오.

그런 다음, 으로 반복 거리 배열을 통해, 뷰에서 전체 UL를 제거, 다시 LI에 지도 각 값은 새로운 UL에 추가, 원래의 UL에서 그것을 뽑아 . 오래된 UL 대신에 새로운 UL을 넣습니다.

이 방법으로 브라우저 다시 그리기는 한 번만 발생하며 이미 계산 된 값을 사용합니다 (elem attrs를 파기하는 것과 반대) sort 함수 내에서.

또한 데이터 attr을 사용하면 lat, lon을 가져 오는 .find ('div with class')보다 빠릅니다.

아래는 이전/새 UL을 숨기거나 표시하지 않기 때문에 각 LI를 이동 한 후에 다시 그리지 만 백엔드 계산량이 훨씬 줄어 듭니다.

var distance_to_li_map = {} 
$('ul li').each(function (index){ 
    var $this = $(this) 
    , locationLat = $this.data("latitude") 
    , locationLong = $this.data('longitude') 
    , distance = getDistance(userLat, locationLat, userLong, locationLong) 

    // store LI elem pointers into map 
    distance_to_li_map[distance] = this 
}) 

var distances = Object.keys(distance_to_li_map) 

distances.sort() 

var newUL = $('<ul></ul>').insertBefore('ul' /*the old UL*/)[0] 

for (var i = 0; i < distances.length; i++) { 
    newUL.appendChild(distance_to_li_map[distances[i]]) 
}; 
+0

코드를 보내 주셔서 감사합니다. 그러나 느린 방법은 원래의 질문은 가장 가까운 상태를 찾는 논리에 대한 것이 었습니다. – hershey

+0

또한 각 li에서 div 클래스를 제거하면 목록 스크롤이 더 좋습니다. {

} – hershey

+0

"이 코드는 방법이 더 느립니다"라는 말에 당황한 것은 여기에 설명 된 정렬에 매우 가깝습니다. http://blog.rodneyrehm.de/archives/14-Sorting-Were-Doing-It-Wrong.html 및 검증 됨 원래 예제에서 가지고있는 코드보다 더 효율적입니다. 링크를보고 권장 사항을 최대한 준수하도록 노력하십시오. – ddotsenko