Tips for sending a changing mouse scroll value as a property in VueJS

I am currently utilizing the Laravel - VueJS framework.

My goal is to detect the Y position of the mouse scroll and pass it dynamically as a prop to a Navbar component. To achieve this, I set up an eventListener and stored the window.scrollY value in a variable called scrollPos within the data(). Then, I passed scrollPos as a prop to the Navbar component using v-bind:scrollPos="scrollPos". However, the value being passed to the Navbar component remains at 0 and does not update with further mouse scrolling.

<Navbar v-on:scroll="this.changeScrollPos" v-bind:scrollPos="scrollPos" />

mounted() {

        console.log('Component mounted.');
        window.addEventListener('scroll', function(e) {
                this.scrollPos = window.scrollY;
                console.log(this.scrollPos);
        });

},
data() {
    return {
        scrollPos: 0
    }
}, 
methods: {
    changeScrollPos() {
        console.log('Mouse scrolled');
    }
}

In the Navbar component, I simply want to display this value in the navigation bar, which is fixed at the top of the page and contains router-links that scroll to specific sections when clicked.

<nav class="nav" id="nav">
    <div class="nav-content>
        <ul class="nav-items">
            <li class="nav-item"><router-link to="/" v-scroll-to="'#section1'">{{ scrollPos }}</router-link></li>
        </ul>
    </div>
</nav>

<script>
    export default {
        props: [
            "scrollPos"
        ]
    }
</script>

I also attempted to use the

v-on:scroll="this.changeScrollPos()"
method to check if this method is triggered after any mouse scroll changes, but it did not work.

If anyone can offer insights into why this setup is not functioning as expected and help me in passing dynamic mouse scroll values to the Navbar component, it would be greatly appreciated.

Edit: While similar to Watch window.scrollY changes in Vuejs, the issue discussed there has been resolved. In my case, the challenge lies in passing the real-time changing mouse scroll value to the component so that the Navbar reflects these updates dynamically.

Answer №1

The issue you are facing is not specific to Vue, but rather a common JavaScript problem related to the this function context.

In a regular function, the value of this can vary depending on how the function was called (Check out this page for more information). In your scenario, the this inside the callback function passed to the addEventListener function will be undefined because it is not bound to anything specific.

mounted() {
  window.addEventListener('scroll', function(e) {
    this.scrollPos = window.scrollY; // this is undefined here 
  });
}

If you want to make this refer to the Vue instance within a regular function, you can manipulate variable scope like this:

mounted() {
  const THIS = this; 
  window.addEventListener('scroll', function(e) {
    THIS.scrollPos = window.scrollY; // THIS refers to the Vue instance here
  });
}

Prior to ES6, this was the commonly used method to achieve this. With ES6 and the introduction of arrow functions, it became much simpler since arrow functions do not bind the this variable:

mounted() {
  window.addEventListener('scroll', e => this.scrollPos = window.scrollY);
}

This approach offers cleaner syntax, which is why it is now preferred. Just keep in mind that arrow functions are not supported in IE11 and below, so you may need to use a pre-compiler like Babel (which you are likely already using).

Answer №2

After taking advice from Slim, I made the decision to refactor my function into an arrow function and surprisingly, it now functions properly. Despite this success, I am still unclear on the reasons behind why this adjustment resolved the issue. It would greatly benefit me if someone could provide a clear explanation.

mounted() {
    window.addEventListener('scroll, () => { this.scrollPos = window.scrollY; });
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Load the values into the dropdown list based on the selection from the previous dropdown menu

Currently, I am working on implementing cloning functionality for select boxes. There are 3 select boxes: country, state, city. The user selects the country first which then populates the state select box based on the ID, and similarly, the city dropdown ...

String variable representing the name of a React element

As I was reviewing the source code of a React UI library, I stumbled upon an interesting code pattern that I will simplify here: function Test() { let Button = "button"; // ... return <Button>Click me</Button>; } I'm curious about ...

Is there a way to switch (transpose) the rows and columns of a dynamically generated HTML table from Highchair in Angular 12?

Click here to view the code for creating a highchart table. In the provided example, I have successfully implemented a highchart table using the code below. Highcharts.chart('container', { title: { text: 'Solar Employment Growth by Sec ...

Is it possible to use JQuery to target input nodes based on their values?

How can I check if any of the file input boxes in my list have a value using just one selector statement? Is it possible to achieve this with code like the following: $('input:file[value!=null]') Or is there another way to accomplish this? ...

Error: A problem occurred that was not caught in the promise, please investigate further

@Injectable() class MyErrorHandler implements ErrorHandler { handleError(error) { // an error occurred in a service class method. console.log('Error in MyErrorhandler - %s', error); if(error == 'Something went wrong'){ ...

Bootstrap - Keeping track of the collapse state of <div> elements after page refresh

Looking for some guidance as a javascript/jquery beginner - I am utilizing Bootstrap along with data-toggle and collapse classes to display or hide divs. I have been searching online trying to find a solution that will maintain the state of all divs, wheth ...

using JavaScript to strip away content following .jpg

var lochash = "#http://www.thepresidiumschool.com/news_image/102%20NRD_7420.jpg&lg=1&slide=0"; I am looking to eliminate or modify the content that comes after .jpg. ...

Chrome is experiencing a problem with anchor tags that have an href attribute set to a "blob:" URL and using a target of "_blank"

My current project involves developing a website feature that allows users to download a PDF version of a page. To achieve this, the generated HTML is rendered into a PDF on the server, which is then returned as a Base64-encoded PDF. This data is converted ...

I'm interested in exploring different database implementation patterns in JavaScript. What kinds of approaches can I consider?

As someone who is relatively new to exploring JavaScript, I have been immersed in experimenting with a node test app and MongoDB. I am eager to delve into the database aspect of the app but finding myself uncertain about the most commonly used patterns in ...

Present a Java-generated JSON object on a JSP page using JavaScript

Hello, I am currently working on creating a Json object in Java and would like to display the same JSON object in JSP using JavaScript. Essentially, I am looking to add two more options in my select box using Ajax. The Ajax is being called and I can see th ...

Load VueSimpleSuggest with values from URL parameter upon page initialization

In my Vue JS application, I have integrated the VueSimpleSuggest component like this: <vue-simple-suggest class="input-elements" v-model="chosen" :max-suggestions="0" :list="getList" :filter-by-query=&qu ...

Troubleshooting AngularJS POST Request Error with Request Body

I am a beginner in AngularJs and I am trying to make a post request to a server with enum form. Currently, I have the following JavaScript code: function completeTaskAction2($scope, $http, Base64) { $http.defaults.headers.common['Authorization'] ...

Encountered an error searching for module 'autoprefixer' while executing the npx tailwindcss init -p command

I am currently working with Vue 3 and attempting to integrate tailwindcss by following this helpful tutorial: https://tailwindcss.com/docs/guides/vue-3-vite#install-tailwind-via-npm I have successfully installed the necessary dependencies using the comman ...

Stopping a velocity.js animation once it has completed: is it possible?

For the pulsating effect I'm creating using velocity.js as a fallback for IE9, refer to box2 for CSS animation. If the mouse leaves the box before the animation is complete (wait until pulse expands and then move out), the pulsating element remains vi ...

Regular pattern with Kubernetes cluster endpoint utilizing either IP address or fully qualified domain name

In my Angular/typescript project, I am working on building a regex for a cluster endpoint that includes an IP address or hostname (FQDN) in a URL format. For instance: Example 1 - 10.210.163.246/k8s/clusters/c-m-vftt4j5q Example 2 - fg380g9-32-vip3-ocs.s ...

Can one manipulate the simulation to make isTrusted=true a reality?

Is there a way to simulate an isTrusted=true in touchStart event triggering? Are there any libraries or workarounds that can make this achievable? When I run the touchStart event programmatically versus physically triggering it, the output differs. Below ...

Animating scrollTop using jQuery is a useful feature for creating

I am facing an issue with several section tags within a div that has overflow set to hidden. The structure of the code is as follows: <div id="viewport"> <section> content </section> <section> content </ ...

What is the best way to change a JSON string into an array of mysterious objects?

I am currently working on a flashcard generator project and I am dealing with a JSON String that is quite complex. The JSON String contains multiple arrays and objects structured like this: data = [{"front":"What is your name?","back":"Billy"},{"front":"H ...

Can a function be called from outside its parent function?

I was pondering the possibility of calling a function from outside its parent function: var $element = $( '.element' ); function myFunction( element ) { var width; function onResize() { width = element.width(); } onResi ...

Sending search queries from a frontend built with React.js to a backend in Express.js: What is the best approach?

I have been attempting to develop a basic search bar using react.js that will communicate with my express.js backend in order to retrieve the accurate data from the database and display it on the front-end. However, I am struggling to grasp how to transmit ...