Global "displayed page change" event


Is there a way to have a global “displayed page change” event?

I would like to send an event to Firebase Analytic every time the user change the page in front of him (whether he has navigated from a page to another, from a routable tab to another, or displayed a routable popup).

I have an app with 3 tabs, a left panel, 3 popups ready to fire, so 7 views at start.
And I have a “routes” file which describe all the routes of my app.

Ideally, I would like to subscribe to a “displayedPageChange” event at the app level which triggers every time the user does an action changing the page in front of him.

Of course, I could build my own stuff, listening to pageChange / popupOpen / popupClose / panelOpen / panelClose / tabChange events at app level, but it is definitely not trivial.

You have to ignore the initial “pageChange” of the non visible views. And when a popup opens, you have to save the previous page so you can send back the event when the popupClose, etc.

And in more complex cases, you could have popup A that opens, then popup B that opens, then an action that close popup A in an invisible way. If we use a dumb “LIFO” management, the popupClose event of popup A would trigger removing the popup B from the “history” pile, which would induce that the currently visible page is popup A and not popup B…

So before starting the creation of this complex stuff, I would like to confirm that there is nothing that already does the trick ! :slight_smile:


PS: if nothing exists, would it be a welcome PR if I can make it happen?

If i will add this to core it will be same “not trivial” event listener but added inside of the core. I think it is for sure better to handle it per app specficially.

Of course :slight_smile: But i see a lot of situations that would extremely hard to cover “by default”, like, as you mentioned, routing in hidden views

A first attempt. It works well enough with my app, but still have some issues.

I observed that $f7.views.current always return the expected view (except for “router generated popups”).
So I simply listen to all the events that can make this value change, and if the value changed, I emit an event.

But as I said, I have issues with router generated popups.

For example, the popups generated by the router does not behave like the popups written at the app level (the last one does not have a popup.route attribute for example, but they emit a pageInit event so they are trackable with the views.current method)

I also have an issue with smart selects in popup generated by the router. When the popup opens, I can get its path thanks to popup.route.path (let’s say /event-create). Then I click on a smart select. It create a pageInit event, and instead of adding its own path to the current path (e.g. /event-create/contacts-select) as it does when on normal pages, it rewrite the path (e.g. /contacts-select). And when I close the smart select, a pageInit event is fired, but instead of having the initial path (/event-create), I have this: /#.

Another issue is with LoginPages: they do not behave like dom popups…

In conclusion, it seems that the $f7.views.current methods is working well, except with routed popups and loginPage…

And at the moment, I am very “dumb” if several popups are opened at the same time…

  let currentlyDisplayedPath = null;
  this.$f7.on('tabShow panelOpen panelClose pageAfterIn popupOpened popupClosed loginScreenOpened loginScreenClosed', (page) => {
    let path = null;
    if (page.type === 'popup' && page.opened && page.route) path = page.route.path;
    else path = this.$f7.views.current.history[this.$f7.views.current.history.length - 1];
    if (currentlyDisplayedPath !== path) {
      currentlyDisplayedPath = path;
      this.$f7.emit('currentPathChanged', path);

  this.$f7.on('currentPathChanged', (path) => {
    console.log('CURRENT PATH', path);