Vueコンポーネントでウィンドウスクロールイベントをリッスンしたい。ここに私がこれまで試したものがあります:
<my-component v-on:scroll="scrollFunction">
...
</my-component>
コンポーネントメソッドでscrollFunction(event)
が定義されていますが、機能していないようです。
誰もこれを行う方法を知っていますか?
ありがとう!
実際に解決策を見つけました。コンポーネントが作成されたときにscroll
イベントにイベントリスナーを追加し、コンポーネントが破棄されたときにイベントリスナーを削除します。
export default {
methods: {
handleScroll (event) {
// Any code to be executed when the window is scrolled
}
},
created () {
window.addEventListener('scroll', this.handleScroll);
},
destroyed () {
window.removeEventListener('scroll', this.handleScroll);
}
}
お役に立てれば!
要件はコンポーネントにありますが、コンポーネントではなくボディに追加することになりました。もちろん、特定の要素でも同様に行うことができますが、ちょっと... Vueカスタムコンポーネントで直接機能するものです。
<MyCustomComponent nativeOnScroll={this.handleScroll}>
または
<my-component v-on:scroll.native="handleScroll">
そしてhandleScrollのメソッドを定義します。シンプル!
私の経験では、スクロールでイベントリスナを使用すると、そのイベントストリームへのパイプが原因で多くのノイズが発生する可能性があり、大きなhandleScroll
関数を実行するとパフォーマンスの問題が発生する可能性があります。
私はここで最も高い評価の回答でここに示すテクニックをよく使用しますが、その上にデバウンスを追加します。通常、100ms
がUX比に対して良好なパフォーマンスをもたらします。
Lodashのデバウンスが追加された最高評価の回答を使用した例を次に示します。
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');
}
},
created() {
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のカスタムディレクティブをまだ見たことがない場合は、これらのディレクティブを学ぶのに最適です。 https://github.com/wangpin34/vue-scroll をご覧ください。
これは、Sarah DrasnerによるVueドキュメントの素晴らしいチュートリアルでもあります。 https://vuejs.org/v2/cookbook/creating-custom-scroll-directives.html
私はこの機能を何度も必要としてきたので、 mixin に抽出しました。次のように使用できます。
import windowScrollPosition from 'path/to/mixin.js'
new Vue({
mixins: [ windowScrollPosition('position') ]
})
これにより、Vueインスタンスにリアクティブposition
プロパティ(好きな名前を付けることができます)が作成されます。このプロパティには、[x,y]
配列としてウィンドウのスクロール位置が含まれます。
この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)
}
}
}