programing

VueJS 컴포넌트에서 윈도 스크롤이벤트를 듣는 방법

prostudy 2022. 5. 30. 22:02
반응형

VueJS 컴포넌트에서 윈도 스크롤이벤트를 듣는 방법

내 Vue 컴포넌트에서 윈도우 스크롤 이벤트를 듣고 싶다.지금까지 제가 시도한 것은 다음과 같습니다.

<my-component v-on:scroll="scrollFunction">
    ...
</my-component>

scrollFunction(event)컴포넌트 메서드에 정의되어 있지만 효과가 없는 것 같습니다.

이거 어떻게 하는지 아는 사람 있어?

감사합니다!

츠미야합니다.scroll컴포넌트가 생성되었을 때의 이벤트와 컴포넌트가 파괴되었을 때의 이벤트청취자를 삭제합니다.

export default {
  created () {
    window.addEventListener('scroll', this.handleScroll);
  },
  destroyed () {
    window.removeEventListener('scroll', this.handleScroll);
  },
  methods: {
    handleScroll (event) {
      // Any code to be executed when the window is scrolled
    }
  }
}

이게 도움이 됐으면 좋겠네요!

으로 인해 할 수 가 큰 가 발생할 수 있습니다.handleScroll★★★★★★ 。

는 종종 가장 답변에 그 그 위에 데바운스를 붙인다.100msUX의

다음은 Lodash debounce가 추가된 상위 등급의 답변을 사용한 예입니다.

import debounce from 'lodash/debounce';

export default {
  methods: {
    handleScroll(event) {
      // Any code to be executed when the window is scrolled
      this.isUserScrolling = (window.scrollY > 0);
      console.log('calling handleScroll');
    }
  },

  mounted() {
    this.handleDebouncedScroll = debounce(this.handleScroll, 100);
    window.addEventListener('scroll', this.handleDebouncedScroll);
  },

  beforeDestroy() {
    // I switched the example from `destroyed` to `beforeDestroy`
    // to exercise your mind a bit. This lifecycle method works too.
    window.removeEventListener('scroll', this.handleDebouncedScroll);
  }
}

값을 .100로로 합니다.0 ★★★★★★★★★★★★★★★★★」1000, 어떻게, 어떻게, 어떻게, 어떻게, 어떻게, 어떻게, 어떻게, 언제, 어떤 가 나는지 알 수.handleScroll출됩니니다다

보너스: 또한 다음과 같은 라이브러리를 사용하여 보다 간결하고 재사용 가능한 방법으로 이 작업을 수행할 수 있습니다.vue-scroll아직 Vue의 커스텀 디렉티브를 참조하지 않은 경우는, Vue의 커스텀 디렉티브에 대해 학습하는 것이 좋은 사용 예입니다.https://github.com/wangpin34/vue-scroll 를 참조해 주세요.

이 튜토리얼은 Sarah Drasner가 Vue documents에서 작성한 훌륭한 튜토리얼입니다.

Vue 3 사용자용

에서는, vue3 의 「Unmount」가 , 「」 「Before Unmount」를 사용할 가 있습니다.beforeDestroy.

Vue3에서 Destroy가 발생하지 않는 라이프 사이클 훅

다음은 Vue 커스텀컴포넌트에서 직접 동작하는 기능입니다.

 <MyCustomComponent nativeOnScroll={this.handleScroll}>

또는

<my-component v-on:scroll.native="handleScroll">

handleScroll 메서드를 정의합니다.심플!

저는 이 기능이 여러 번 필요했기 때문에 믹스인에 추출했습니다.다음과 같이 사용할 수 있습니다.

import windowScrollPosition from 'path/to/mixin.js'

new Vue({
  mixins: [ windowScrollPosition('position') ]
})

.positionVue 인스턴스의 속성(이름 지정 가능)을 지정합니다.에는 창 가 ""로 됩니다.[x,y]manager.manager로 하다

CodeSandbox 데모를 마음껏 사용해 보세요.

여기 믹스인의 코드가 있습니다.자세한 코멘트가 붙어 있기 때문에, 동작의 구조를 파악하는 것은 어렵지 않습니다.

function windowScrollPosition(propertyName) {
  return {
    data() {
      return {
        // Initialize scroll position at [0, 0]
        [propertyName]: [0, 0]
      }
    },
    created() {
      // Only execute this code on the client side, server sticks to [0, 0]
      if (!this.$isServer) {
        this._scrollListener = () => {
          // window.pageX/YOffset is equivalent to window.scrollX/Y, but works in IE
          // We round values because high-DPI devies can provide some really nasty subpixel values
          this[propertyName] = [
            Math.round(window.pageXOffset),
            Math.round(window.pageYOffset)
          ]
        }

        // Call listener once to detect initial position
        this._scrollListener()

        // When scrolling, update the position
        window.addEventListener('scroll', this._scrollListener)
      }
    },
    beforeDestroy() {
      // Detach the listener when the component is gone
      window.removeEventListener('scroll', this._scrollListener)
    }
  }
}

오래된 질문이지만 Vue.js 2.0+ Custom Directives에서 더 나은 솔루션을 찾았습니다.스크롤 이벤트도 바인드해야 했고, 그리고 나서 이 기능을 구현했습니다.

우선, 사용@vue/cli커스텀 디렉티브를 에 추가합니다.src/main.js(Vue.js 인스턴스 이전) 또는 Vue.js 인스턴스를 시작하는 곳:

Vue.directive('scroll', {
  inserted: function(el, binding) {
    let f = function(evt) {
      if (binding.value(evt, el)) {
        window.removeEventListener('scroll', f);
      }
    }
    window.addEventListener('scroll', f);
  }
});

다음으로 커스텀을 추가합니다.v-scroll바인드할 요소 및/또는 컴포넌트에 대한 지시어를 지정합니다.물론 전용 메서드를 삽입해야 합니다.나는 사용했다handleScroll제 예에서는요.

<my-component v-scroll="handleScroll"></my-component>

마지막으로 컴포넌트에 메서드를 추가합니다.

methods: {
  handleScroll: function() {
    // your logic here
  }
}

커스텀 디렉티브 자체에서는 Vue.js 라이프 사이클에 신경 쓸 필요가 없습니다.

가장 좋은 방법은 ".passive"를 추가하는 것입니다.

v-on:scroll.passive='handleScroll'

이런 건 어때?그런데 여기는 Vue 3입니다.

setup() {
    function doOnScroll(event) {
      window.removeEventListener("scroll", doOnScroll);
      console.log("stop listening");
      // your code here ....
      setTimeout(() => {
        window.addEventListener("scroll", doOnScroll, { passive: true });
        console.log("start listening");
      }, 500);
    }

    window.addEventListener("scroll", doOnScroll, { passive: true });
  }

여기서의 아이디어는 스크롤이벤트를 한 번만 듣고 스크립트를 실행한 후 스크롤 리스너를 다시 접속하는 것입니다.setTimeout기능.이 지연 후에도 페이지가 계속 스크롤 중인 경우 스크롤 이벤트가 다시 처리됩니다.기본적으로 스크롤 이벤트는 500ms마다 한 번만 재생됩니다(이 예에서는).

스크롤 중에 css 클래스를 추가하여 버튼을 이동할 때 사용합니다.

이렇게 해도 컴포넌트가 새로 고쳐지지 않습니다.Vux를 사용하여 vuex "페이지"용 모듈을 생성하여 문제를 해결했습니다.

export const state = {
    currentScrollY: 0,
};

export const getters = {
    currentScrollY: s => s.currentScrollY
};

export const actions = {
    setCurrentScrollY ({ commit }, y) {
        commit('setCurrentScrollY', {y});
    },
};

export const mutations = {
    setCurrentScrollY (s, {y}) {
       s.currentScrollY = y;
    },
};

export default {
    state,
    getters,
    actions,
    mutations,
};

App.vue:

created() {
    window.addEventListener("scroll", this.handleScroll);
  },
  destroyed() {
    window.removeEventListener("scroll", this.handleScroll);
  },
  methods: {
    handleScroll () {
      this.$store.dispatch("page/setCurrentScrollY", window.scrollY);
      
    }
  },

컴포넌트:

  computed: {
    currentScrollY() {
      return this.$store.getters["page/currentScrollY"];
    }
  },

  watch: {
    currentScrollY(val) {
      if (val > 100) {
        this.isVisibleStickyMenu = true;
      } else {
        this.isVisibleStickyMenu = false;
      }
    }
  },

효과가 좋습니다.

document.addEventListener('scroll', function (event) {
    if ((<HTMLInputElement>event.target).id === 'latest-div') { // or any other filtering condition
  
    }
}, true /*Capture event*/);

이를 사용하여 이벤트를 캡처할 수 있습니다.여기서 "latest-div"는 ID 이름입니다.따라서 이 ID에 따라 모든 스크롤러 액션을 캡처할 수 있습니다.

조합하여this.$vuetify.breakpoint.name를 사용하여 필요에 따라 로딩하는 스크롤 이벤트는 매우 유용한 기능입니다.

방아쇠를 당기다.예를 들어 탭:

<v-tabs
  v-bind:grow="!isFullScreen()"
  v-bind:vertical="isFullScreen()"
>

일부 클래스 속성:

private isUserScrolling: boolean = false;
private isLoaded: boolean = false;
private startScroll: number = 3;

트리거에 반응하는 기능(필요한 경우 조정):

private isFullScreen(): boolean {
    switch (this.$vuetify.breakpoint.name) {
      case "xs":
        this.startScroll = 500;
        return false;
      case "sm":
        this.startScroll = 300;
        return false;
      case "md":
        this.startScroll = 100;
        return true;
      case "lg":
        this.startScroll = 50;
        return true;
      case "xl":
        this.startScroll = 3;
        return true;
    }
}

이벤트 추가:

created() {
   window.addEventListener("scroll", this.handleScroll);
}

이벤트에 대한 반응:

private handleScroll(event: any): void {
   this.isUserScrolling = window.scrollY > this.startScroll;
   
   if (this.isUserScrolling && !this.isLoaded) {
     // load your stuff
     ...
     this.isLoaded = true;
   }
}

언급URL : https://stackoverflow.com/questions/45822150/how-to-listen-to-the-window-scroll-event-in-a-vuejs-component

반응형