我在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
};
//这是带有lat和long坐标的列表的代码
<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 :(得分:1)
JavaScript的排序是O(n) - 换句话说,它不止一次触及每个元素。这意味着你执行.data(在同一个元素上多次调用,并且你也多次移动它,每次触发浏览器重绘。
不要对元素进行排序,对其“距离”数组进行排序。
然后,从视图中删除整个UL, 迭代距离数组, 将每个值映射回LI 从原始的UL中采摘它, 将其附加到新的UL。 将新的UL替换为旧的UL。
这样浏览器重绘只发生一次,你在sort函数中使用已经计算过的值(而不是挖掘elem attrs)。
此外,使用数据attr比.find('div with class')快拉lat,lon。
以下内容不会隐藏/显示旧/新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]])
};
答案 1 :(得分: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
:
<li data-latitude="31.375626" data-longitude="-86.299592">
<a href="#page2" data-transition="slide" >Alabama</a>
</li>
应该比隐藏的div更好地保存数据。
更好的方法是在javascript中对所有lat / long对进行硬编码,从而避免从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”开头