Javascripts targeting the footer doesn't work after page transitions

I have written a css to make the footer menu responsively. When we navigate to mobile devices, footer menus are designed as similar to hamburger menu. So I have written a click function on Edit Css/Html >> /head section to toggle the menus in mobile view.

Here the click function was working fine on discourse home page. But some other pages like Summary, Forum Account, etc…, pages, script was blocked. So I cannot able to see the sub menus. And I can able to see the script in browser source also.

Why the custom scripts execution was blocked in some pages on discourse ? What is the permanent fix for this issue ?

Discourse is a single-page application. So, the scripts you add in the <head> tag only fire once on the initial page load unless you use the right hooks. You probably need to tweak your code to add an event listener instead.

Can you share your code?

3 Likes

Here is my script,

There’s probably a few ways to address this, but let’s try the “proper” way using the right customization hooks.

When you add HTML to the footer section of a theme, Discourse does some handling for that so that it doesn’t jump around between page transitions or when more elements are added with infinite scroll.

It gets added as a custom-html component here.

https://github.com/discourse/discourse/blob/a0bbc346cb5d5b89d1a3efdfa89869349a8b067f/app/assets/javascripts/discourse/app/templates/application.hbs#L31

If you look at the component code, you’ll see that it fires an app event when it’s rendered.

https://github.com/discourse/discourse/blob/a0bbc346cb5d5b89d1a3efdfa89869349a8b067f/app/assets/javascripts/discourse/app/components/custom-html.js#L24-L29

This is the hook you need to use.

How do you use it?
There’s a method in the plugin-api that lets you fire code when a specific app event is fired.

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/lib/plugin-api.js#L507-L519

Since we already know the event name, we can use that like so

api.onAppEvent("inserted-custom-html:footer", () => {
  // do your work here
});

Since this is a plugin-API method, you need to change your script tag’s type to text/discourse-plugin like so

<script type="text/discourse-plugin" version="0.8">
api.onAppEvent("inserted-custom-html:footer", () => {
  // do your work here
});
</script>

The snippet above will fire whenever the footer is rendered. So, you can now do something like this.

<script type="text/discourse-plugin" version="0.8">
api.onAppEvent("inserted-custom-html:footer", () => {
  $(".footer-div #footerNavDiv").click(function () {
    console.log("click event captured");
    // do your work here for the click event
  });
});
</script>

You can read more about the plugin-API here

5 Likes

Awesome, thank you :slight_smile:

1 Like