[Solved] EventListener gotcha in Hugo?

I am new to Hugo and have been playing around with it for a few days now. I’m writing all the code for my Hugo site on my own with no theme help and I can’t understand why the following JavaScript code does not work in Hugo but will in a regular index.html ran on a live server from VS Code:

Resides inside {{ partial "scripts" . }} and is injected near the bottom of the <body/> of the baseof.html template.

<script type="text/javascript">
  const nav = document.querySelector('#main')
  const offset = nav.offsetTop
  // Fixed Navigation Menu
  function fixNav() {
    if (window.scrollY >= offset) {
      document.body.style.paddingTop = `${nav.offsetHeight}px`
      document.body.classList.add('fixed-nav')
    } else {
      document.body.style.paddingTop = 0
      document.body.classList.remove('fixed-nav')
    }
  }
  window.addEventListener('scroll', fixNav)
</script>

I can verify that a scroll event is being attached to the window object in Chrome, but no scroll event is executing. I’ve been trying to find similar issues and added the type/javascript to the tag, but that did help out any either. Is there a gotcha with Hugo I’m not understanding about executing JavaScript?

It should be {{ partial "scripts.html" . }} You didn’t include the extension and Hugo cannot find the partial.

@alexandros all the partial render fine leaving the .html off. I can see my scripts and other partials in the devtools

That’s news to me. According the docs a partial in Hugo templates uses the following pattern:

{{ partial "<PATH>/<PARTIAL>.html" . }} From here

EDIT
Also there’s been some discussion in the past about calling partials without the .html extension. See: [FIXED] Calling partial without specifying .html suffix

I see I went ahead and put .html on everything, but no matter what I’m doing the scroll event will not be registered. I gave this a try but nothing:

<script type="text/javascript">
  window.addEventListener('scroll', () => {
   console.log(window.scrollY)
   console.log('scrolling')
  })
 </script>

Nothing, not a single thing get’s logged yet the dev tools show that the scroll event is attached to the window.

@rockchalkwushock your issue is JS related.

Hint:

@alexandros offsetTop is a property off of document.querySelector('#main') so I’m not seeing what is wrong?

56

From MDN

Constants are block-scoped, much like variables defined using the let statement. The value of a constant cannot change through re-assignment, and it can’t be redeclared.

You should have used let not const

But I am overstepping forum rules by pointing this out. We do not offer JS support here.

I understand what you are saying about the block-scope and that JS help is not what this forum is for.

I’m retrieving where the top of the <nav /> is and storing that value as a constant. The comparison is looking at window.scrollY which will be dynamic as the user scrolls so as soon as it exceeds 480 in this case whatever magic is called in the if block happens. I would not want both values to be dynamic.

The issue I’m having is that the scroll event is being put on the window object, but it is never firing. The code I presented earlier #5 was nothing more than a console.log(window.scrollY) inside the scroll event. It should be logging out a value that is changing as I scroll, but I get nothing. That’s why I asked if there is some sort of gotcha about event listeners with Hugo.

If there was a problem with Hugo the console would have thrown an error and the site would not have been generated.

I have encountered a similar problem with a script in a partial once. Removing the partial and calling the script with a link from my template fixed that issue for me.

So do try this suggestion and see what happens.

If your issue is resolved when you call the script with a link, then come back here and post a link to the source of your project so that the Devs can look at it.

If your issue is not resolved when the script is called as a link then I’m afraid that there are problems with your JS. Stack Overflow will be a better place to look for a solution.

@alexandros

It seems as if the code will only run as expected at the top level. It cannot be run from a partial and I cannot get it to run from any template in the _default/.

My code that works at /layouts/index.html

<script type="text/javascript">
  const nav = document.getElementById('menu')
  const offset = nav.offsetTop
  window.addEventListener('scroll', () => {
    console.log(window.scrollY, offset)
    if (window.scrollY >= offset) {
      document.body.style.paddingTop = `${nav.offsetHeight}px`
      document.body.classList.add('fixed-nav')
     } else {
      document.body.style.paddingTop = 0
      document.body.classList.remove('fixed-nav')
     }
  })
</script> 

I have tried making a partial specifically for that code and injecting it in the baseof.html, list.html, & single.html as well as defining a block in the baseof and passing that exact code but the scroll event will only ever fire at the top level index.html.

I don’t know enough about golang at all to begin trying to figure out why that would be. Any ideas?

My question now is how to add this code when the page changes to /posts/ etc. if it in fact will only work at the top level? Would I have to go about making posts.html etc?

I’ve currently got this marked as private repository. I will make it public and link her with the branch the dev team can look at.

Hugo uses Go Templates. And they can be quirky. But I am afraid that I cannot help you further. I have never encountered the sort of issue you describe.

Once you share your repo maybe Hugo’s maintainer can look into your issue of not being able to run a JS script from within a partial but only from the top level index.html (I’m summarizing your issue to make it easier for him).

@alexandros

No need…I figured it out there was a discrepancy with the CSS. The base styling for the parallax effect was nullifying the ability for the scroll event to be heard.

Aha! Then do mark the topic as solved.