skip to Main Content

I want to execute this script within the astro framework to adjust the placement of my footer at the end of the page if the page is shorter than the viewport (if there is a better way tell me, but it’s not the problem here):

    window.onload = function () {
        const footer = document.querySelector('footer')
        if (!footer) return
        const bodyHeight = document.body.clientHeight
        const windowHeight = window.innerHeight
        if (bodyHeight < windowHeight) {
            footer.style.position = 'absolute'
            footer.style.bottom = '0'
            footer.style.width = '100%'
        }
    }

But because it’s asynchronous document.body.clientHeight is equal to 0 9 times on 10 and window.onload handler change nothing. I also tried body.onload but same thing.

Here is my crappy hotfix:

    window.onload = function () {
        const footer = document.querySelector('footer')
        if (!footer) return
        footer.style.display = 'none'
        setTimeout(function () {
            const bodyHeight = document.body.clientHeight
            const windowHeight = window.innerHeight
            if (bodyHeight < windowHeight) {
                footer.style.position = 'absolute'
                footer.style.bottom = '0'
                footer.style.width = '100%'
            }
            footer.style.display = 'block'
        }, 100) // Let the page load first
    }

3

Answers


  1. You don’t need to use JavaScript to do this effect.
    Take a look at this for example:

    function AddContentToExemple() {
      const contentElement = document.querySelector("main");
      contentElement.append("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum");
    }
    :root {
      --footer-height: 20px;
    }
    
    main {
      min-height: calc(100vh - var(--footer-height));
      padding: 40px 40px 0 40px;
      box-sizing: border-box;
    }
    
    body {
      margin: 0;
    }
    
    footer {
      height: var(--footer-height);
      background-color: red;
      color: white;
    }
    <main>
      <p>You can add text by clicking on the button bellow :</p>
      <button onclick="AddContentToExemple()">Add Content</button>
    </main>
    <footer class="footer">
      Footer
    </footer>
    Login or Signup to reply.
  2. No sure if it will resolve your issue, but I would first try to use this event listener instead of window.onload:

      document.addEventListener("DOMContentLoaded", (event) => {
          console.log("DOM fully loaded and parsed");
      });
    
    Login or Signup to reply.
  3. I don’t know what your CSS looks like but for the JS part:

    You are using setTimeout to delay the execution of your logic/function.

    I would recommend using Promise.resolve().

    It is similar idea but little bit more elegant since rather than waiting for arbitrary time set in your setTimout function, it is scheduled to run in the next cycle of the event loop, after all the other functions on the stack trace have returned.

    Your code would look like this:

     window.onload = function () {
            const footer = document.querySelector('footer')
            if (!footer) return
            footer.style.display = 'none'
            Promise.resolve(()=>{
                const bodyHeight = document.body.clientHeight
                const windowHeight = window.innerHeight
                if (bodyHeight < windowHeight) {
                    footer.style.position = 'absolute'
                    footer.style.bottom = '0'
                    footer.style.width = '100%'
                }
                footer.style.display = 'block'
              }
            ) // Let the page load first
    }
    

    Give it a go!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search