I'm trying to add a mouseover event listener to a Google Maps overlay view. I've been following this question, but can't get the listener to work. This is my code:
InfoWindow.prototype = new google.maps.OverlayView;
InfoWindow.prototype.onAdd = function() {
this.getPanes().overlayMouseTarget.appendChild(this.$content.get(0));
this.getPanes().overlayMouseTarget.parentNode.style.zIndex = 100000;
google.maps.event.addListener(this, 'mouseover', function() {
console.log('MOUSEOVER');
});
};
This doesn't give any errors, but also doesn't do anything on mouseover. I've also tried using this.listeners:
this.listeners = [
google.maps.event.addDomListener(this, "mouseover", function (e) {
console.log('MOUSEOVER');
})
];
but it doesn't help either. What am I doing wrong?
For the domListener to work, you need to attach it to a dom node:
google.maps.event.addDomListener(this.$content.get(0), "mouseover", function (e) {
console.log('MOUSEOVER');
});
Related
Is it possible to set something like context menu or spoiler over map, using HERE?
If you know, how to do it, please, let me know,i'll appreciate it
You can listen for a 'contextmenu' event on the map instance. Here is an example:
map.addEventListener('contextmenu', function (evt) {
evt.items.push(new H.util.ContextItem({
label: 'Zoom in',
callback: function () {
map.setZoom(map.getZoom() + 1);
}
}));
});
I create custom handler by extending L.Handler and add handler for map click event in addHooks method. From outer code, I`m add handler for click event, too. I use L.DomEvent.stop(e) in custom handler, but event propagate and outer code handle it. It seems like a bug.
const map = L.map("map", {
boxZoom: false
}).setView([39.50, -98.35], 5);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
L.CustomHandler = L.Handler.extend({
initialize: function(map) {
this._map = map;
},
addHooks: function() {
this._map
.on('click', this._onMapClick, this)
},
_onMapClick: function(e) {
L.DomEvent.stop(e.originalEvent);
console.log('map click from handler');
},
removeHooks: function() {
this._map
.off('click', this._onMapClick, this);
},
});
map.addHandler('customHandler', L.CustomHandler);
map.customHandler.enable();
map.on('click', (e) => console.log('map click'));
See my plunker pls https://plnkr.co/edit/yuh67rrsOZYSpUjXam4g?p=preview
I'm having a problem with the event listeners provided by Google maps API. The thing is, that some events run, some not. I have a setListeners function which sets the listeners after the polygon overlay is complete. The events I would like to hook are: set_at, insert_at, remove_at and click. Now the click events run correctly, but the others not. What could I do wrong? Here is the code:
self.setListeners = function () {
//this click event runs correctly
google.maps.event.addListener(self.map, 'click', function (e) {
self.clearSelection();
})
console.log(self.drost);
if (typeof self.drost != 'undefined') {
self.drost.addListener('set_at', function (e) {
console.log(e.overlay);
});
self.drost.addListener('insert_at', function (e) {
console.log(e.overlay);
});
self.drost.addListener('remove_at', function (e) {
console.log(e.overlay);
});
//this click also runs correctly
self.drost.addListener('click', function(e){
self.setSelection(self.drost);
})
}
}
The events set_at, insert_at, remove_at need to be added to the path of the polygon, not the polygon itself.
related questions:
Apply event listener to an editable polygon
calculate area of a drawn polygon on google map javascript
Try adding the listener with google.maps.event:
google.maps.event.addListener(self.drost, 'set_at', function() {
console.log('it works!');
});
Anyone know why that, when clicked, the buttons do not add or remove overlays from the map? Full PLNKR here
The HTML
<div id="toggleButtons" style="display: none">
<button id="add">Add Overlays</button>
<button id="remove">Remove Overlays</button>
</div>
The Javascript
L.Control.GroupedLayers.include({
addOverlays: function () {
for (var i in this._layers) {
if (this._layers[i].overlay) {
if (!this._map.hasLayer(this._layers[i].layer)) {
this._map.addLayer(this._layers[i].layer);
}
}
}
},
removeOverlays: function () {
for (var i in this._layers) {
if (this._layers[i].overlay) {
if (this._map.hasLayer(this._layers[i].layer)) {
this._map.removeLayer(this._layers[i].layer);
}
}
}
}
});
var control = new L.Control.GroupedLayers(ExampleData.Basemaps, {
'Landmarks': {
'Cities': ExampleData.LayerGroups.cities,
'Restaurants': ExampleData.LayerGroups.restaurants
},
'Random': {
'Dogs': ExampleData.LayerGroups.dogs,
'Cats': ExampleData.LayerGroups.cats
}
}).addTo(map);
L.DomEvent.addListener(L.DomUtil.get('add'), 'click', function () {
control.addOverlays();
});
L.DomEvent.addListener(L.DomUtil.get('remove'), 'click', function () {
control.removeOverlays();
});
And then I added the mapbox legendControl.addLegend method (from the mapbox API documentation)
map.legendControl.addLegend(document.getElementById('toggleButtons').innerHTML);
Although the buttons are shown in the map, their click properties are not working. Any clues? Thanks!
You're not 'adding' the buttons with javascript, you're making a copy of them and placing the copy into the legendControl. The actual buttons with the eventhandlers are still present in the DOM but hidden because you've added display: none as inline style. What you want to do is select the buttons and remove them from the body:
var buttons = document.getElementById('toggleButtons');
document.body.removeChild(buttons);
Then you can add them to the legend and attach the eventhandlers:
var legendControl = L.mapbox.legendControl().addTo(map);
legendControl.addLegend(buttons.innerHTML);
L.DomEvent.addListener(L.DomUtil.get('add'), 'click', function () {
control.addOverlays();
});
L.DomEvent.addListener(L.DomUtil.get('remove'), 'click', function () {
control.removeOverlays();
});
Working example on Plunker: http://plnkr.co/edit/7pDkrZbS7Re1YshKZSLs?p=preview
PS. I'm quite baffled as to why you would abuse mapbox's legend control class to add two buttons. If you need a custom control you can just create one using leaflet's L.Control class. It spares you from loading the legend control class which you're not using, thus bloat.
EDIT: As promised in the comments below an example of rolling this solution into your own custom control. I'll explain to more throughout the comments in the code but the general idea is take the basic L.Control interface and adding the functionality and DOM generation to it:
// Create a new custom control class extended from L.Control
L.Control.Toggle = L.Control.extend({
// Have some default options, you can also change/set
// these when intializing the control
options: {
position: 'topright',
addText: 'Add',
removeText: 'Remove'
},
initialize: function (control, options) {
// Add the options to the instance
L.setOptions(this, options);
// Add a reference to the layers in the layer control
// which is added to the constructor upon intialization
this._layers = control._layers;
},
onAdd: function (map) {
// Create the container
var container = L.DomUtil.create('div', 'control-overlaystoggle'),
// Create add button with classname, append to container
addButton = L.DomUtil.create('button', 'control-overlaystoggle-add', container),
// Create remove button with classname, append to container
removeButton = L.DomUtil.create('button', 'control-overlays-toggleremove', container);
// Add texts from options to the buttons
addButton.textContent = this.options.addText;
removeButton.textContent = this.options.removeText;
// Listen for click events on button, delegate to methods below
L.DomEvent.addListener(addButton, 'click', this.addOverlays, this);
L.DomEvent.addListener(removeButton, 'click', this.removeOverlays, this);
// Make sure clicks don't bubble up to the map
L.DomEvent.disableClickPropagation(container);
// Return the container
return container;
},
// Methods to add/remove extracted from the groupedLayerControl
addOverlays: function () {
for (var i in this._layers) {
if (this._layers[i].overlay) {
if (!this._map.hasLayer(this._layers[i].layer)) {
this._map.addLayer(this._layers[i].layer);
}
}
}
},
removeOverlays: function () {
for (var i in this._layers) {
if (this._layers[i].overlay) {
if (this._map.hasLayer(this._layers[i].layer)) {
this._map.removeLayer(this._layers[i].layer);
}
}
}
}
});
Now you can use your new control as follows:
// Create a new instance of your layer control and add it to the map
var layerControl = new L.Control.GroupedLayers(baselayers, overlays).addTo(map);
// Create a new instance of your toggle control
// set the layercontrol and options as parameters
// and add it to the map
var toggleControl = new L.Control.Toggle(layerControl, {
position: 'bottomleft',
addText: 'Add overlays',
removeText: 'Remove overlays'
}).addTo(map);
I know, this is quick and dirty but it should give you a decent idea of what you can do with the L.Control class in general.
Here's a working example on Plunker: http://plnkr.co/edit/7pDkrZbS7Re1YshKZSLs?p=preview
And here's the reference for L.Control: http://leafletjs.com/reference.html#control
You need to follow delegation strategy here..
document.querySelector('body').addEventListener('click', function(event) {
if (event.target.id.toLowerCase() === 'add') {
control.addOverlays();
}
if (event.target.id.toLowerCase() === 'remove') {
control.removeOverlays();
}
});
I'm trying to disable the zoom on the map when I click in a CircleMarker object, but until now, no success.
This is my code:
var myCircle = new L.CircleMarker(new L.LatLng(50.924480, 10.758276), 10).addTo(map);
myCircle.on("click", function () {
//my click stuff
});
myCircle.on("dblclick", function () {
//my dblclick stuff
});
Everytime the dblclick event is fired, the map is zoomed, how to disable it?
try
var myCircle = new L.CircleMarker(new L.LatLng(50.924480, 10.758276), 10).addTo(map);
map.doubleClickZoom.disable();
refer this document
All answers here are after the Leaflet map object has been initialized.
I'd like to give my take by stating that you can also disable doubleClickZoom during map object initialization.
Note: This will disable doubleClickZoom to the whole map and not just circleMarkers.
map = L.map('map', {
center: [39.8282, -98.5795],
zoom: 5,
doubleClickZoom: false
});
P.S. I'm running leaflet version 1.7.1
Following solution seems to work for me:
myCircle.ondblclick = function (event) {
event.stopPropagation();
return false;
};
I have also tried another one, which also works quite well in practice, but I find it a bit hacky:
myCircle.on("click", function () {
map.doubleClickZoom.disable();
setTimeout(function(){map.doubleClickZoom.enable();}, 1000);
});
None of the answers above worked for me:
calling native ev.originalEvent.preventDefault() did nothing
returning false neither
I don't like the doubleClickZoomworkaround that much (although… it works!)
Using Leaflet DomEvent did the job for me:
import { DomEvent } from 'leaflet';
myFeature.on("dblclick", function (ev) {
DomEvent.stopPropagation(ev)
});
If anyone is here looking for a solution to the use case "I want to zoom in on the map on double-click but not if the double-click happens on an entity", this is how I solved it:
const circle = new L.circlemarker(...).addTo(map);
circle.on("dblclick", () => {
map.doubleClickZoom.disable();
doSomething();
setTimeout(() => {
map.doubleClickZoom.enable();
}, 1); // Without the timeout the map will still zoom in on entity double-click
});
FYI event.preventDefault(); event.stopPropagation(); and return false; inside the "dblclick" handler did not work for me.
You can return false from your dblclick handler which will stop the event from propagating e.g.
myCircle.on("dblclick", function () {
//my dblclick stuff
return false;
});
Now other elements (such as the map) won't handle that event
Try this... Disable map.doubleClickZoom when you mouse over the circle and enable when you leave
var myCircle = new L.CircleMarker(new L.LatLng(50.924480, 10.758276), 10).addTo(map);
myCircle
.on("click", function () {
//my click stuff
})
.on("dblclick", function () {
//my dblclick stuff
})
.on('mouseover', function () {
map.doubleClickZoom.disable();
})
.on('mouseout', function () {
map.doubleClickZoom.enable();
});
First you need to disable the map double click zoom and then enable it again on the map click event. So when you double click the map after double clicking on the marker it zoom again ;) I tried it and it works for me perfectly! Enjoy!
map.doubleClickZoom.disable();
map.on('click', function (e) {
map.doubleClickZoom.enable();
});