2

I'm new in frontend developement, I'm using Vue.js and I want to create a sticky navbar. I found this method but I didn't find how to embed this JavaScript code in my .vue file.

window.onscroll = function() {myFunction()};

var navbar = document.getElementById("navbar");
var sticky = navbar.offsetTop;

function myFunction() {
  if (window.pageYOffset >= sticky) {
    navbar.classList.add("sticky")
  } else {
    navbar.classList.remove("sticky");
  }
}

I've dropped the navbar and sticky variables in data and the function in the methods but it won't work.

<script>
window.onscroll = function() {myFunction()};

export default {
  name: "About",
  data() {
    return {
      navbar : document.getElementById("navbar"),
      sticky : navbar.offsetTop

    }},
    methods: {
       handleScroll (event) {
         if (window.pageYOffset >= sticky) {
    navbar.classList.add("sticky")
  } else {
    navbar.classList.remove("sticky");
  }

    }}
<script>


EDIT:

I've just done it and the whole page is blank now

here is the whole .vue file

<template>
  <div class="about">
    <div class="header">
     <h2>Scroll Down</h2>
      <p>Scroll down to see the sticky effect.</p>
    </div>

    <div id="navbar">
      <a class="active" href="javascript:void(0)">Home</a>
      <a href="javascript:void(0)">News</a>
      <a href="javascript:void(0)">Contact</a>
    </div>

    <div class="content">
      <h3>Sticky Navigation Example</h3>
      <p>The navbar will stick to the top when you reach its scroll position.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
    </div>
  </div>
</template>

<script>
window.addEventListener('scroll', this.onScroll);

export default {
  name: "About",
  data() {
    return {
      navbar : document.getElementById("navbar"),
      sticky : navbar.offsetTop

    }},
    methods: {
       onScroll () {
         if (window.pageYOffset >= sticky) {
    navbar.classList.add("sticky")
  } 
  else {
    navbar.classList.remove("sticky");
  }

    }
      // Any code to be executed when the window is scrolled

  }}


</script>

<style scoped>
  body {
  margin: 0;
  font-size: 28px;
  font-family: Arial, Helvetica, sans-serif;
}

.header {
  background-color: #f1f1f1;
  padding: 30px;
  text-align: center;
}

#navbar {
  overflow: hidden;
  background-color: #333;
}

#navbar a {
  float: left;
  display: block;
  color: #f2f2f2;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 17px;
}

#navbar a:hover {
  background-color: #ddd;
  color: black;
}

#navbar a.active {
  background-color: #4CAF50;
  color: white;
}

.content {
  padding: 16px;
}

.sticky {
  position: fixed;
  top: 0;
  width: 100%;
}

.sticky + .content {
  padding-top: 60px;
}
</style>
3
  • You are missing </script> closing tag Commented Dec 27, 2019 at 13:57
  • You should use the mounted lifecycle of your component to add the event listener. it would be probably better to replace window.onscroll by windo.addEventListener('scroll', this.onScroll). You then define a onScroll method to your component which will modify the state of the component. Then in your template you add the class depending on the state Commented Dec 27, 2019 at 13:59
  • I've just done it and the whole page is blank now Commented Dec 27, 2019 at 14:12

2 Answers 2

3

You could try something like this:

<script>
export default {
    data: {},
      mounted: function() {
        window.addEventListener('scroll', this.scrollHandle)
      },
      methods: {
          scrollHandle() {
              var navbar = document.getElementById("navbar");
              var sticky = navbar.offsetTop;

              if (window.pageYOffset >= sticky) {
                  navbar.classList.add("sticky")
              } else {
                    navbar.classList.remove("sticky");
              }
          },
      }
}
</script>

You set your event handler in the mounted function so it'll be run before the component is loaded entirely. This way you'll get your scrolling where you need like in the vanilla js example.

Although this will work you should try to avoid manipulating the DOM since VUE uses VirtualDOM. It's a good habit to get into as it's consider better practice, and you'll find it make maintenance down the road much easier should you need to revisit your component later on.

As an alternative to using JS and DOM manipulation you can look into using CSS position:sticky for a css approach, instead of handling that with javascript. Something like this would do the trick from CSS:

<template>
    ...
    <div id="nav" class="sticky">
       ...
    </div>
    ...
</template>
<style>
...
.sticky {
    position: sticky;
    top: 0em;
}
...
<style>
Sign up to request clarification or add additional context in comments.

3 Comments

If it helps more to see an example that's working, then here is a fiddle to illustrate a CSS approach jsfiddle.net/CoderLee/hunt8qwr/5
it is working perfectly, thanks However I haven't clearly understand your note about the DOM manipulation (I'm still beginner and maybe that will be helpful for me)
Glad to hear that helped! That's ok, look up the links in the answer for better explanations. Half the fun of coding is learning new things about it!
0

I've just done it and the whole page is blank now

here is the whole .vue file

<template>
  <div class="about">
    <div class="header">
      <h2>Scroll Down</h2>
      <p>Scroll down to see the sticky effect.</p>
    </div>

    <div id="navbar">
      <a class="active" href="javascript:void(0)">Home</a>
      <a href="javascript:void(0)">News</a>
      <a href="javascript:void(0)">Contact</a>
    </div>

    <div class="content">
      <h3>Sticky Navigation Example</h3>
      <p>The navbar will stick to the top when you reach its scroll position.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
      <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
    </div>
  </div>
</template>

<script>
window.addEventListener('scroll', this.onScroll);

export default {
  name: "About",
  data() {
    return {
      navbar : document.getElementById("navbar"),
      sticky : navbar.offsetTop

    }},
    methods: {
       onScroll () {
         if (window.pageYOffset >= sticky) {
    navbar.classList.add("sticky")
  } 
  else {
    navbar.classList.remove("sticky");
  }

    }
      // Any code to be executed when the window is scrolled

  }}


</script>

<style scoped>
  body {
  margin: 0;
  font-size: 28px;
  font-family: Arial, Helvetica, sans-serif;
}

.header {
  background-color: #f1f1f1;
  padding: 30px;
  text-align: center;
}

#navbar {
  overflow: hidden;
  background-color: #333;
}

#navbar a {
  float: left;
  display: block;
  color: #f2f2f2;
  text-align: center;
  padding: 14px 16px;
  text-decoration: none;
  font-size: 17px;
}

#navbar a:hover {
  background-color: #ddd;
  color: black;
}

#navbar a.active {
  background-color: #4CAF50;
  color: white;
}

.content {
  padding: 16px;
}

.sticky {
  position: fixed;
  top: 0;
  width: 100%;
}

.sticky + .content {
  padding-top: 60px;
}
</style>

1 Comment

You should consider adding this to your post as an edit, since it's not an answer. That'll make it easier for others to help answer your questions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.