I've added custom buttons to my MapBox map and they shop up correctly. However when I add a click listener it does not work. I see no error in my console.
The code looks like this:
const currentLocationControl = new CustomControl('current-location-control', 'GPS');
this.map.addControl(currentLocationControl, 'top-left');
document.getElementById('test').addEventListener('click', function (e) {
alert('test');
});
I execute this code in the mounted
method from vue.js
.
The CustomControl:
export default class CustomControl {
constructor(className, text) {
this.className = className;
this.text = text;
}
onAdd(map){
this.map = map;
this.container = document.createElement('div');
this.container.id = 'test';
this.container.className = this.className;
this.container.textContent = this.text;
return this.container;
}
onRemove(){
this.container.parentNode.removeChild(this.container);
this.map = undefined;
}
}
When I console.log(document.getElementById('test'));
I see the expected result in my console (the test div).
So what could be going on here?
I've added custom buttons to my MapBox map and they shop up correctly. However when I add a click listener it does not work. I see no error in my console.
The code looks like this:
const currentLocationControl = new CustomControl('current-location-control', 'GPS');
this.map.addControl(currentLocationControl, 'top-left');
document.getElementById('test').addEventListener('click', function (e) {
alert('test');
});
I execute this code in the mounted
method from vue.js
.
The CustomControl:
export default class CustomControl {
constructor(className, text) {
this.className = className;
this.text = text;
}
onAdd(map){
this.map = map;
this.container = document.createElement('div');
this.container.id = 'test';
this.container.className = this.className;
this.container.textContent = this.text;
return this.container;
}
onRemove(){
this.container.parentNode.removeChild(this.container);
this.map = undefined;
}
}
When I console.log(document.getElementById('test'));
I see the expected result in my console (the test div).
So what could be going on here?
Share Improve this question edited Apr 10, 2018 at 9:42 Jenssen asked Apr 7, 2018 at 17:21 JenssenJenssen 1,8815 gold badges44 silver badges77 bronze badges 6- 1 It's most likely due to the fact that you're building this in javascript so it's not available in the DOM when you're attempting to bind to use. use event delegation off of the closest static parent element instead – Ohgodwhy Commented Apr 7, 2018 at 17:51
- Anyone????!?!?! – Jenssen Commented Apr 8, 2018 at 14:06
- 1 Did you attempt what I told you? – Ohgodwhy Commented Apr 8, 2018 at 14:48
- @ohgodwhy it's within a vue.js ponent so there is no static parent right? Thanks for helping. – Jenssen Commented Apr 8, 2018 at 15:32
- Just put a breakpoint at that speciffic line and check if the element is trully there. Also, the event can be bound but the button may appear under the map, so you actually click on themap not the button. Do you have correct z-indexes? – knaos Commented Apr 17, 2018 at 8:21
2 Answers
Reset to default 2To make sure that the click event is bind to the correct element, you can bind the event in the Class declaration instead.
Pass a callback for click event to the CustomControl
const clickCallback = function(e) {
alert(test);
};
const currentLocationControl = new CustomControl(
"current-location-control",
"GPS",
clickCallback
);
Class declaration:
// add clickCallback to constructor
export default class CustomControl {
constructor(className, text, clickCallback) {
//...
}
onAdd(map) {
//...
this.container.onclick = clickCallback;
//...
}
}
It might very well be the element does not yet exist, depending on how map.addControl
works.
Perhaps if you created a method in your CustomControl
to return the container, and instead of using document.getElementById
you'd use something like currentLocationControl.getContainer()
?
Alternatively a setAction
in your CustomControl
like
setAction(action) {
this.container.addEventListener('click', action);
}