gpt4 book ai didi

javascript - 禁用 Google map Javascript 自定义控件上的拖动

转载 作者:行者123 更新时间:2023-11-28 04:27:29 25 4
gpt4 key购买 nike

我想使用 Javascript API 创建 Google map 自定义控件。

该控件是一个“添加航点”按钮。用户应该能够从控件中拖动,使鼠标指针处出现一个标记,然后将该标记放到 map 上。

预期行为与现有的街景小人功能几乎相同。

问题在于 Google map 控件似乎与拖动交互,即使已明确禁用拖动,如下所示。

在示例代码中,我第一次单击并拖动时,它按预期工作。第二次单击并拖动时,我会看到一个“禁止拖动”图标,并且控件会产生自己的幽灵。第三次拖动时,它又起作用了。下一次拖动时,会显示“无拖动”。该序列继续,奇数拖动起作用,偶数拖动失败。

以下是我认为相关的部分:

<div id="map"></div>
<script>
var spawning = false;
var inProgress = false;
var waypointSpawner;
var targetLat;
var targetLng;

function initMap()
{
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 0.0000, lng: 0.0000},
zoom: 2
});

// Create the DIV to hold the control and call the CenterControl()
// constructor passing in this DIV.
var centerControlDiv = document.createElement('div');
var centerControl = new CenterControl(centerControlDiv, map);

centerControlDiv.index = 1;
map.controls[google.maps.ControlPosition.LEFT_TOP].push(centerControlDiv);
}

function CenterControl(controlDiv, map) {

// Set CSS for the control border.
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = '#fff';
controlUI.style.border = '2px solid #fff';
controlUI.style.borderRadius = '3px';
controlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
controlUI.style.cursor = 'pointer';
controlUI.style.marginBottom = '22px';
controlUI.style.width = '40px';
controlUI.style.height = '50px';
controlUI.style.opacity = "0.7";
controlUI.style.backgroundImage = "url('create_waypoint_icon.png')";
controlUI.title = 'Add Waypoint';
controlUI.draggable = "false";


//controlDiv.draggable = "false";
controlDiv.appendChild(controlUI);
}

我无法让上面的代码在 jsfiddle 中工作,但是还有一些其他示例可以说明该问题。

http://jsfiddle.net/maunovaha/jptLfhc8/

尝试拖放 map 左上角的蓝色和绿色方 block 会导致一些意外行为。根据您的缩放级别,并且有些随机,您将得到各种不同的结果 -

1 - 什么也没发生。指针保持为手指状态并正常移动。
2 - 手指指针变为“无拖动”,但其他方面移动正常。
3 - 手指指针变为“禁止拖动”和蓝色和绿色半透明的“粘贴”小部件。
4 - 手指指针变为“无拖动”,小部件的蓝色或绿色一半(取决于您的选择)随之变化。

这种行为在 Google 控件示例代码中也有些明显:
https://developers.google.com/maps/documentation/javascript/examples/control-custom

在这种情况下,当文本突出显示时,您会看到“禁止拖动”图标。父控件似乎不可选,这是期望的目标。

我相信自定义控件正在获取某种“焦点”状态,并且再次单击它会清除焦点。这种行为在绿色/蓝色示例中很明显。也许该控件正在以某种方式“突出显示”?

我尝试实现 How can I make a div unselectable? 中给出的解决方案没有效果。我还尝试了多种方法使代码中的div不可拖动,但这似乎没有任何影响。

我还尝试模拟鼠标单击程序的其他部分,然后双击控件,以更改焦点/突出显示状态,但看来 API 并未实际执行单击,仅从中生成事件。我找不到一种方法来引起“真正的”点击。手动单击,然后单击并拖动就可以了。

我还尝试使控件可拖动,但即使拖动它,它仍然具有“不可拖动”鼠标指针。

最佳答案

如果我正确理解您的意思,您希望能够从外部将标记拖到 map 上,并在该位置上放置一个点。

我有以下解决方案可以做到这一点。

首先我们需要构建 map :

function buildMap() {
var g = google.maps;
var mapOptions = {
center: new g.LatLng(52.052491, 9.84375),
zoom: 4,
mapTypeId: g.MapTypeId.ROADMAP,
streetViewControl: false,
panControl: false
};
map = new g.Map(document.getElementById("map"), mapOptions);
iw = new g.InfoWindow();
g.event.addListener(map, "click", function() {
if (iw) iw.close()
});
drag_area = document.getElementById("markers");
var b = drag_area.getElementsByTagName("div");
b[0].onmousedown = initDrag
dummy = new DummyOView()
}

我们创建一个标准 map 并添加 infoWindows 等功能,以便在添加标记时显示经纬度。

此外,我们还可以获取标记所在的位置,并在 onMouseDown 上调用一个函数(即将推出)。

我们使用b[0]因为我们得到了第一组 <div>下面标记中的标签,这是可拖动图标所在的位置:

<div id="markers">
<div id="m1" class="drag" style="left:0; background-image: url('https://maps.gstatic.com/mapfiles/ms/icons/ltblue-dot.png')">
</div>
</div>

DummyOView 是一个 map OverlayView,它允许我们拖动到 map 上并获取坐标和位置。有关 SO 的更多信息 + 致谢:More info

function DummyOView() {
this.setMap(map);
this.draw = function() {}
}

DummyOView.prototype = new google.maps.OverlayView();

initDrag 函数是完成大部分工作的地方,这是一个相当冗长的函数,因此我对代码进行了注释,任何有关澄清的问题只需添加注释即可。

//function that allows us to drag the marker from the div to the map
function initDrag(e) {
//allows us to drag the marker and keep record of the clientX client Y coordinates
var j = function(e) {
var a = {};
if (!e) var e = window.event;
a.x = e.clientX;
a.y = e.clientY
return a
};
//function called whenever the mouse moves. this will keep track of the marker as we move around
var k = function(e) {
//check to ensure that the object is of class drag - otherwise we could drag everything
if (obj && obj.className == "drag") {
var i = j(e),
deltaX = i.x - l.x,
deltaY = i.y - l.y;
obj.style.left = (obj.x + deltaX) + "px";
obj.style.top = (obj.y + deltaY) + "px";
obj.onmouseup = function() {
//get the information to check to see if the dragObj is on the map on mouse up
var a = map.getDiv(),
mLeft = a.offsetLeft,
mTop = a.offsetTop,
mWidth = a.offsetWidth,
mHeight = a.offsetHeight;
var b = drag_area.offsetLeft,
areaTop = drag_area.offsetTop,
oWidth = obj.offsetWidth,
oHeight = obj.offsetHeight;
//check to see if obj is in bounds of map div X and Y
var x = obj.offsetLeft + b + oWidth / 2;
var y = obj.offsetTop + areaTop + oHeight / 2;
if (x > mLeft && x < (mLeft + mWidth) && y > mTop && y < (mTop + mHeight)) {
var c = 1;
var mapTemp = google.maps;
var point = new mapTemp.Point(x - mLeft - c, y - mTop + (oHeight / 2));
var proj = dummy.getProjection();
var latlng = proj.fromContainerPixelToLatLng(point);
var backImage = obj.style.backgroundImage.slice(4, -1).replace(/"/g, "");
createDraggedMarker(latlng, backImage);
fillMarker(backImage)
}
}
}
return false
};

//assign the event to a windows event
obj = e.target ? e.target : e.srcElement;
//if the object where the event took place is not called drag cancel the event
if (obj.className != "drag") {
if (e.cancelable) e.preventDefault();
obj = null;
return
} else {
z_index += 1;
obj.style.zIndex = z_index.toString();
obj.x = obj.offsetLeft;
obj.y = obj.offsetTop;

var l = j(e); //get the initial position of the marker relative to the client

document.onmousemove = k;
//if we lift the mouse up outside the map div set to null and leave where it is
document.onmouseup = function() {
document.onmousemove = null;
document.onmouseup = null;
if (obj) obj = null
}
}
return false
}

总结一下,只要单击并拖动鼠标,就会调用此函数。它注册了起始位置和 map div 的位置,并在 onmouseup 时检查当前鼠标位置是否位于 map div 上方。如果是这样,我们在 map 上创建一个标记,并将标记图标重新添加到 div 以允许重新拖动。

//when the marker is dragged onto the map
//we call this function to create a marker on the map
function createDraggedMarker(position, iconImage) {
var mapLocal = google.maps;
var icon = {
url: iconImage,
size: new mapLocal.Size(32, 32),
anchor: new mapLocal.Point(15, 32)
};
var marker = new mapLocal.Marker({
position: position,
map: map,
clickable: true,
draggable: true,
crossOnDrag: false,
optimized: false,
icon: icon,
zIndex: highestOrder()
});

mapLocal.event.addListener(marker, "click", function() {
actual = marker;
var lat = actual.getPosition().lat();
var lng = actual.getPosition().lng();
var innerHtml = "<div class='infowindow'>" + lat.toFixed(6) + ", " + lng.toFixed(6) + "<\/div>";
iw.setContent(innerHtml);
iw.open(map, this)
});
mapLocal.event.addListener(marker, "dragstart", function() {
if (actual == marker) iw.close();
z_index += 1;
marker.setZIndex(highestOrder())
})
}

将标记重新添加到 div

//Used to replace the marker
//once we have moved it from its div
function fillMarker(a) {
var div = document.createElement("div");
div.style.backgroundImage = "url(" + a + ")";
var padding;
if (obj.id == "m1") {
padding = "0px"
}
div.style.left = padding;
div.id = obj.id;
div.className = "drag";
div.onmousedown = initDrag;
drag_area.replaceChild(div, obj);
obj = null
}

JSfiddle 您可以使用:https://jsfiddle.net/q3wjrpdw/7/

有任何问题请随时提问。

关于javascript - 禁用 Google map Javascript 自定义控件上的拖动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44910605/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com