我使用JSON数据填充了Google地图,我有一个复选框来选择要在地图上显示的数据类别。 当我点击复选框时,它通过Ajax调用一个新的JSON数据,当我取消选中一个框时,它会循环显示所有标记的数组,并删除所有未选中类别的标记。
它大部分时间都有效,但有时标记会消失并再次出现。似乎他们仍然在阵列或其他东西......
$( "input[type=checkbox]" ).change(function() {
var data ='';
var checkbox = $(this);
var checkboxVal = $(this).val();
console.log('click');
if (checkbox.is(':checked')) {
$('.loader').show();
$("input:checkbox[name=poi_categories]:checked").each(function() {
data = data + checkboxVal + ',';
$.ajax({
type: "POST",
url: window.location.pathname,
data: "categorie=" + data,
success:function(response){
json = JSON.parse(response);
for (var i = 0; i < json.length; i++) {
createMarker(json[i], data);
}
$('.loader').hide();
}
});
});
} else {
for (var i in markersArray) {
if ( markersArray[i] != undefined) {
if( null == markersArray[i].cat || markersArray[i].cat == checkboxVal) {
markersArray[i].setMap(null);
delete(markersArray[i]);
}
}
}
}
});
我很确定在最后一个for循环中有一个错误,但我看不出...
编辑:
以下是整个Js代码:http://jsfiddle.net/5bMQm/
答案 0 :(得分:1)
for (var i = 0, l = markersArray.length; i < l; i++) {
if ( markersArray[i] != undefined) {
if( null == markersArray[i].cat || markersArray[i].cat == checkboxVal) {
markersArray[i].setMap(null);
markersArray.splice(i, 1);
i--; l--;
}
}
}
答案 1 :(得分:1)
完全误解了。每次用户单击复选框时,您都会多次执行此操作 - 这也是您要从markersArray中删除从地图中删除的标记的原因。
认为我找到了潜在的问题。
你有
createMarker(json[i], data);
但仅
function createMarker(marker) {
你设置
cat : marker.img
但与
比较markersArray[i].cat == checkboxVal
你假设(我猜)应该包含
var checkboxVal = $(this).val();
..
data = data + checkboxVal + ',';
但永远不会! 数据/复选框永远不会分配给您的标记!
for (var i in markersArray) {
if ( markersArray[i] != undefined) {
if( null == markersArray[i].cat || markersArray[i].cat == checkboxVal) {
markersArray[i].setMap(null);
markersArray[i] = undefined; // <---
}
}
}
//cleanup
for (var i=markersArray.length;i>0;i--) {
if (markersArray[i]==undefined]) {
markersArray.splice(i, 1);
}
}
答案 2 :(得分:0)
它大部分时间都有效,但有时标记会消失并再次出现。似乎他们仍然在数组或其他东西
当所有内容按预期工作时,您的代码正如预期的那样对我有用。
但是问题(假设您的服务器端脚本的返回响应总是正确的):
你不能指望AJAX响应按照它们发出的顺序到达(有时单个请求可能会有很大的延迟)。它可以是例如发生在你身上。
当响应按相反顺序到达时,您将创建标记,尽管当前未选中该框。
可能的解决方案:(但有一个更好的解决方案,见下文)
在createMarker
if(!$('input[type="checkbox"][name="poi_categories"][value="'+marker.img+'"]').is(':checked'))return;
另一个问题:您的脚本中似乎有一个reduntant部分,
$("input:checkbox[name=poi_categories]:checked").each(function() {
/*ajax-code*/
});
这对我没有任何意义,假设您已选中5个复选框,而最后点击的复选框的值为例如“酒店”,您将发送categories=hotel,hotel,hotel,hotel,hotel
,我认为您的服务器端脚本不会返回任何标记。您根本不需要遍历已检查的标记。
这应该足够了:
if (checkbox.is(':checked')) {
$('.loader').show();
$.ajax({
type: "POST",
url: window.location.pathname,
data: "categorie=" + checkboxVal,
success:function(response){
json = JSON.parse(response);
for (var i = 0; i < json.length; i++) {
createMarker(json[i], data);
}
$('.loader').hide();
}
});
}
这是避免重大问题的更好解决方案的一个好点。不是在创建标记之前检查复选框的checked属性,而是最好中止最近的请求:
var checkbox = $(this);
var checkboxVal = $(this).val();
console.log('click');
//if there has been a recent request, abort it
if(checkbox.data('xhr')){
checkbox.data('xhr').abort();console.log('recent request aborted');
}
if (checkbox.is(':checked')) {
$('.loader').show();
data = data + checkboxVal + ',';
//store the jqXhr within the checkbox-data
//to be able to abort it later
checkbox.data('xhr',$.ajax({
type: "POST",
url: window.location.pathname,
data: "categorie=" + checkboxVal,
success:function(response){
json = JSON.parse(response);
for (var i = 0; i < json.length; i++) {
createMarker(json[i], data);
}
$('.loader').hide();
}
}));
} else {/* your code*/}