AlexLavoie42 / Nuxt-Mapbox

Elegant Mapbox integration with Nuxt
81 stars 11 forks source link

`MapboxDefaultPopup` inner HTML events don't work #38

Closed uwaovo closed 10 months ago

uwaovo commented 1 year ago

Environment: OS: MacOSX 13.4 Node: v18.16.0 Nuxt: 3.5.3 Nuxt-Mapbox: 1.3.8

Screenshot: Capture-2023-06-07-210959

Reproduce: Online Playground(just add a button from given)

Expected Behavior: Alert Wow!

Actual Behavior: Nothing happens

It seems that it is related to mapboxgl: https://stackoverflow.com/questions/68066479/onclick-not-working-in-my-popup-button-mapoboxgl, is there any recommended way to make them work, please give me some suggestion in nuxt-mapbox, thanks🙏.

AlexLavoie42 commented 1 year ago

Yes, this is more of a mapbox issue. The way the html gets added to the popup involves copying it as a string and removing the original which breaks events. (but hopefully I can workaround it at some point, I will basically have to parse the HTML to find the event listenners though)

Unfortunately there is not really a good way of accessing the popup instance inside the defaultPopup (I will work on this in the next update). You could either make your own popup with defineMapboxPopup (Keep in mind reactivity will not work unless you add it manually), or you could access the internal $mapboxPopupInstances function with the nuxt app. This will return ALL of the current popup instances in object with their id as the key.

Here is an example of using $mapboxPopupInstances:

As of v1.4.0 you can now access the popup with useMapboxPopup.

The workaround now looks like this:

useMapboxPopup('<POPUP_ID>', (popup) => {
    popup.getElement().addEventListener('click', () => {
      // your logic here
    });
})
AlexLavoie42 commented 1 year ago

Keeping this open as a reminder for the next update

aonghas commented 1 year ago

Is this supposed to be working yet?

AlexLavoie42 commented 1 year ago

No this is still WIP.

There is a new way to access the popup with useMapboxPopup. So the workaround now would just look like this:

useMapboxPopup('<POPUP_ID>', (popup) => {
    popup.getElement().addEventListener('click', () => {
      // your logic here
    });
})

Again, keep in mind this will put the event listener only on the root div.

aonghas commented 1 year ago

cool, and how do I write it so that it only adds the event listener when the popup has been loaded in the DOM? Currently getting undefined errors if I just put that function in the setup() directly...

AlexLavoie42 commented 1 year ago

I believe the problem is the popup is initialized before the html actually gets loaded (I will work on fixing this in the next update). For now wrapping useMapboxPopup in useMapbox, or calling useMapboxPopup in the maps load event should fix the issue. You could also try calling it in onMounted but I can't guaranteed that will work.

johnghr commented 1 year ago

No this is still WIP.

There is a new way to access the popup with useMapboxPopup. So the workaround now would just look like this:

useMapboxPopup('<POPUP_ID>', (popup) => {
    popup.getElement().addEventListener('click', () => {
      // your logic here
    });
})

Again, keep in mind this will put the event listener only on the root div.

Is it possible to use this workaround to add an event listener to a child of the root, like on a button for example?

AlexLavoie42 commented 1 year ago

Is it possible to use this workaround to add an event listener to a child of the root, like on a button for example?

popup.getElement() returns a normal HTMLElement. You can use this to access the children in many ways (see Element properties

AlexLavoie42 commented 10 months ago

Fixed in #73