我正在为地图创建一个标记列表,当它们被拖动到地图上时(通过jquery draggable) - 图像将替换为地图标记。
我遇到的问题是,在创建标记控制器时 - 它们每个都有一个特定类型 - 从列表中提取。当我遍历列表时,每个可拖动元素都会被赋予其'stop'函数,该函数使用变量'type'...现在当每个元素被拖动时 - 它们都表现为它们是最后一个的'类型'元素,而不是他们自己的。
有人可以建议我如何重组这个,以便每个标记保持其特定类型吗?
var createMarkerControl = function(){
var markerTypes = ['custom', 'exit', 'food', 'medical', 'shelter', 'video'];
var control = document.createElement('div');
control.setAttribute('id', 'markerInput');
for (var i = 0; i < markerTypes.length; i++){
var image = document.createElement('img');
image.setAttribute('id', 'draggable-' + markerTypes[i]);
image.setAttribute('src', 'images/gui/' + markerTypes[i] + '.png');
image.style.width = '30px';
//Set type
var type = markerTypes[i];
//Make elements dragable/dropable
control.appendChild(image);
$(image).draggable({
helper: 'clone',
stop: function(e){
//Add marker to map
var point = new google.maps.Point(e.pageX, e.pageY);
customMap.addPlacemark(point, type);
},
cursorAt: {left: 15, top: 0}
});
}
map.controls[google.maps.ControlPosition.RIGHT_CENTER].push(control);
}
答案 0 :(得分:3)
这是因为JavaScript没有块级范围,只有功能级范围。 image
和type
变量的范围限定为createMarkerControl
,而不是循环。更重要的是,它们的范围是在之外的可拖动闭包,因此每个闭包都将共享type
变量。
我认为你希望你的内循环看起来更像这样:
var createMarkerControl = function(){
var markerTypes = ['custom', 'exit', 'food', 'medical', 'shelter', 'video'];
var control = document.createElement('div');
control.setAttribute('id', 'markerInput');
var createDraggable = function(image, type) {
image.setAttribute('id', 'draggable-' + type);
image.setAttribute('src', 'images/gui/' + type + '.png');
image.style.width = '30px';
//Make elements dragable/dropable
control.appendChild(image);
$(image).draggable({
helper: 'clone',
stop: function(e){
//Add marker to map
var point = new google.maps.Point(e.pageX, e.pageY);
customMap.addPlacemark(point, type);
},
cursorAt: {left: 15, top: 0}
});
};
for (var i = 0; i < markerTypes.length; i++){
var image = document.createElement('img');
//Set type
var type = markerTypes[i];
createDraggable(image, type);
}
map.controls[google.maps.ControlPosition.RIGHT_CENTER].push(control);
}
通过将逻辑放在子函数中,可以确保对type
和image
的引用对于内部闭包是唯一的。
答案 1 :(得分:2)
我不认为JavaScript中的for
循环会获得自己的变量范围(就像它们有时会在其他语言中一样),因此您定义的type
变量绑定在函数的范围内。所以你真的需要另一个坚实的范围。
我个人会为您生成一个帮助函数,为您生成stop
个闭包。这将创建一个稳定的范围,你的关闭可以生活...像这样:
var createMarkerControl = function(){
var markerTypes = ['custom', 'exit', 'food', 'medical', 'shelter', 'video'];
var control = document.createElement('div');
control.setAttribute('id', 'markerInput');
for (var i = 0; i < markerTypes.length; i++){
var image = document.createElement('img');
image.setAttribute('id', 'draggable-' + markerTypes[i]);
image.setAttribute('src', 'images/gui/' + markerTypes[i] + '.png');
image.style.width = '30px';
//Set type
var type = markerTypes[i];
//Make elements dragable/dropable
control.appendChild(image);
$(image).draggable({
helper: 'clone',
stop: createStopper(type),
cursorAt: {left: 15, top: 0}
});
}
map.controls[google.maps.ControlPosition.RIGHT_CENTER].push(control);
}
var createStopper = function(type) {
return function(e){
var point = new google.maps.Point(e.pageX, e.pageY);
customMap.addPlacemark(point, type);
}
}
答案 2 :(得分:0)
试试这个:
$(image).data('type',type).draggable({
helper: 'clone',
stop: function(e){
//Add marker to map
var point = new google.maps.Point(e.pageX, e.pageY);
customMap.addPlacemark(point, $(this).data('type'));
},
cursorAt: {left: 15, top: 0}
});
在您的代码中,type
循环中每次迭代都会覆盖for
,但在任何给定的迭代中type
的值永远不会附加到可拖动的图像上,而是简单地在stop
回调中引用。在stop
被触发时,type
值就在它的最后一次分配上。我在上面提供的想法是简单地将type
的值附加到对象,以便它可以在回调中从内部引用它。
答案 3 :(得分:0)
我知道正确的答案已经发布并且它们很好但是一个简单的(IMHO)解决方案只是在(function(){ ... })();
中包装您需要的代码,以便创建一个新的范围。
var createMarkerControl = function(){
var markerTypes = ['custom', 'exit', 'food', 'medical', 'shelter', 'video'];
var control = document.createElement('div');
control.setAttribute('id', 'markerInput');
for (var i = 0; i < markerTypes.length; i++)
(function() {
var image = document.createElement('img');
image.setAttribute('id', 'draggable-' + markerTypes[i]);
image.setAttribute('src', 'images/gui/' + markerTypes[i] + '.png');
image.style.width = '30px';
//Set type
var type = markerTypes[i];
//Make elements dragable/dropable
control.appendChild(image);
$(image).draggable({
helper: 'clone',
stop: function(e){
//Add marker to map
var point = new google.maps.Point(e.pageX, e.pageY);
customMap.addPlacemark(point, type);
},
cursorAt: {left: 15, top: 0}
});
})();
map.controls[google.maps.ControlPosition.RIGHT_CENTER].push(control);
}