scaccogatto / vue-waypoint Goto Github PK
View Code? Open in Web Editor NEWtrigger functions and events based on the element position on the screen
License: MIT License
trigger functions and events based on the element position on the screen
License: MIT License
Hey! I'm working with vue-waypoint and it works really nice but when I go to Edge 15 the callback function (onWaypoint) doesn't run so my elements get always hidden, never showing up when entring the viewport. Any idea what might be the cause
Thanks!
Looks like 'going' is changing to 'out' in an inconsistent way when the threshold is not 0 or 1.
On the example looks like it works when scrolling the page to top or bottom really fast.
Unfortunately, shipping .ts
files in your npm package causes errors that cannot be bypassed in vue-tsc
and is generally not recommended. Is there a reason to ship .ts
files on top of the js distributables and not prebuilt js with declaration files?
Example errors in snippet below:
../../node_modules/vue-waypoint/src/components/Waypoint/component.ts:63:58 - error TS2345: Argument of type '{ readonly attributes: { [x: number]: { readonly localName: string; readonly name: string; readonly namespaceURI: string | null; readonly ownerDocument: { readonly URL: string; alinkColor: string; readonly all: { [x: number]: ...; readonly length: number; item: (nameOrIndex?: string | undefined) => Element | ... 1 m...' is not assignable to parameter of type 'Element'.
Types of property 'attributes' are incompatible.
Type '{ [x: number]: { readonly localName: string; readonly name: string; readonly namespaceURI: string | null; readonly ownerDocument: { readonly URL: string; alinkColor: string; readonly all: { [x: number]: { readonly attributes: ...; ... 165 more ...; readonly assignedSlot: { ...; } | null; }; readonly length: number; ...' is not assignable to type 'NamedNodeMap'.
'number' index signatures are incompatible.
Type '{ readonly localName: string; readonly name: string; readonly namespaceURI: string | null; readonly ownerDocument: { readonly URL: string; alinkColor: string; readonly all: { [x: number]: { readonly attributes: { [x: number]: ...; ... 8 more ...; [Symbol.iterator]: () => IterableIterator<...>; }; ... 165 more ...; r...' is not assignable to type 'Attr'.
The types of 'ownerDocument.anchors' are incompatible between these types.
Type '{ [x: number]: { charset: string; coords: string; download: string; hreflang: string; name: string; ping: string; referrerPolicy: string; rel: string; readonly relList: { [x: number]: string; readonly length: number; ... 13 more ...; [Symbol.iterator]: () => IterableIterator<...>; }; ... 308 more ...; username: stri...' is not assignable to type 'HTMLCollectionOf<HTMLAnchorElement>'.
'number' index signatures are incompatible.
Type '{ charset: string; coords: string; download: string; hreflang: string; name: string; ping: string; referrerPolicy: string; rel: string; readonly relList: { [x: number]: string; readonly length: number; value: string; ... 12 more ...; [Symbol.iterator]: () => IterableIterator<...>; }; ... 308 more ...; username: stri...' is not assignable to type 'HTMLAnchorElement'.
Types of property 'shadowRoot' are incompatible.
Type '{ readonly delegatesFocus: boolean; readonly host: { readonly attributes: { [x: number]: { readonly localName: string; readonly name: string; readonly namespaceURI: string | null; readonly ownerDocument: { readonly URL: string; ... 256 more ...; evaluate: (expression: string, contextNode: Node, resolver?: XPathNSRes...' is not assignable to type 'ShadowRoot | null'.
Type '{ readonly delegatesFocus: boolean; readonly host: { readonly attributes: { [x: number]: { readonly localName: string; readonly name: string; readonly namespaceURI: string | null; readonly ownerDocument: { readonly URL: string; ... 256 more ...; evaluate: (expression: string, contextNode: Node, resolver?: XPathNSRes...' is not assignable to type 'ShadowRoot'.
Types of property 'childNodes' are incompatible.
Type '{ [x: number]: { after: (...nodes: (string | Node)[]) => void; before: (...nodes: (string | Node)[]) => void; remove: () => void; replaceWith: (...nodes: (string | Node)[]) => void; readonly baseURI: string; ... 48 more ...; removeEventListener: (type: string, callback: EventListenerOrEventListenerObject | null, opt...' is not assignable to type 'NodeListOf<ChildNode>'.
'number' index signatures are incompatible.
Type '{ after: (...nodes: (string | Node)[]) => void; before: (...nodes: (string | Node)[]) => void; remove: () => void; replaceWith: (...nodes: (string | Node)[]) => void; readonly baseURI: string; ... 48 more ...; removeEventListener: (type: string, callback: EventListenerOrEventListenerObject | null, options?: boolean ...' is not assignable to type 'ChildNode'.
Types of property 'parentElement' are incompatible.
Type '{ accessKey: string; readonly accessKeyLabel: string; autocapitalize: string; dir: string; draggable: boolean; hidden: boolean; inert: boolean; innerText: string; lang: string; readonly offsetHeight: number; ... 281 more ...; focus: (options?: FocusOptions | undefined) => void; } | null' is not assignable to type 'HTMLElement | null'.
Type '{ accessKey: string; readonly accessKeyLabel: string; autocapitalize: string; dir: string; draggable: boolean; hidden: boolean; inert: boolean; innerText: string; lang: string; readonly offsetHeight: number; ... 281 more ...; focus: (options?: FocusOptions | undefined) => void; }' is not assignable to type 'HTMLElement'.
Types of property 'assignedSlot' are incompatible.
Type '{ name: string; assign: (...nodes: (Element | Text)[]) => void; assignedElements: (options?: AssignedNodesOptions | undefined) => Element[]; ... 292 more ...; focus: (options?: FocusOptions | undefined) => void; } | null' is not assignable to type 'HTMLSlotElement | null'.
Type '{ name: string; assign: (...nodes: (Element | Text)[]) => void; assignedElements: (options?: AssignedNodesOptions | undefined) => Element[]; ... 292 more ...; focus: (options?: FocusOptions | undefined) => void; }' is not assignable to type 'HTMLSlotElement'.
The types of 'style.parentRule' are incompatible between these types.
Type '{ cssText: string; readonly parentRule: ... | null; readonly parentStyleSheet: { readonly cssRules: { [x: number]: ...; readonly length: number; item: (index: number) => CSSRule | null; [Symbol.iterator]: () => IterableIterator<...>; }; ... 14 more ...; readonly type: string; } | null; ... 10 more ...; readonly SUPP...' is not assignable to type 'CSSRule | null'.
Type '{ cssText: string; readonly parentRule: ... | null; readonly parentStyleSheet: { readonly cssRules: { [x: number]: ...; readonly length: number; item: (index: number) => CSSRule | null; [Symbol.iterator]: () => IterableIterator<...>; }; ... 14 more ...; readonly type: string; } | null; ... 10 more ...; readonly SUPP...' is not assignable to type 'CSSRule'.
Types of property 'parentStyleSheet' are incompatible.
Type '{ readonly cssRules: { [x: number]: { cssText: string; readonly parentRule: ... | null; readonly parentStyleSheet: ... | null; readonly type: number; readonly STYLE_RULE: 1; readonly CHARSET_RULE: 2; ... 7 more ...; readonly SUPPORTS_RULE: 12; }; readonly length: number; item: (index: number) => CSSRule | null; [Sym...' is not assignable to type 'CSSStyleSheet | null'.
Type '{ readonly cssRules: { [x: number]: { cssText: string; readonly parentRule: ... | null; readonly parentStyleSheet: ... | null; readonly type: number; readonly STYLE_RULE: 1; readonly CHARSET_RULE: 2; ... 7 more ...; readonly SUPPORTS_RULE: 12; }; readonly length: number; item: (index: number) => CSSRule | null; [Sym...' is not assignable to type 'CSSStyleSheet'.
Types of property 'ownerNode' are incompatible.
Type '{ readonly attributes: { [x: number]: { readonly localName: string; readonly name: string; readonly namespaceURI: string | null; readonly ownerDocument: { readonly URL: string; alinkColor: string; readonly all: { [x: number]: ...; readonly length: number; item: (nameOrIndex?: string | undefined) => Element | ... 1 m...' is not assignable to type 'Element | ProcessingInstruction | null'.
Type '{ readonly attributes: { [x: number]: { readonly localName: string; readonly name: string; readonly namespaceURI: string | null; readonly ownerDocument: { readonly URL: string; alinkColor: string; readonly all: { [x: number]: ...; readonly length: number; item: (nameOrIndex?: string | undefined) => Element | ... 1 m...' is not assignable to type 'Element | ProcessingInstruction | null'.
63 if (activable.value) return observer.value.observe(element.value);
~~~~~~~~~~~~~~
../../node_modules/vue-waypoint/src/components/Waypoint/component.ts:64:44 - error TS2345: Argument of type '{ readonly attributes: { [x: number]: { readonly localName: string; readonly name: string; readonly namespaceURI: string | null; readonly ownerDocument: { readonly URL: string; alinkColor: string; readonly all: { [x: number]: ...; readonly length: number; item: (nameOrIndex?: string | undefined) => Element | ... 1 m...' is not assignable to parameter of type 'Element'.
64 else return observer.value.unobserve(element.value);
~~~~~~~~~~~~~~
Found 2 errors in the same file, starting at: ../../node_modules/vue-waypoint/src/components/Waypoint/component.ts:63
Hello! I'm currently relying on toggling the active state in the runtime, but the latest published version on npm is 3.4.1.
Could you publish the latest version so it's in-line with the state on github, please?
Using Nuxt.js having threshold like the following:
data () {
return {
wayPointOptions: {
root: null,
rootMargin: '0px 0px 0px 0px',
threshold: Array(101).join(0).split(0).map((n, i) => (i) / 100) // [0.00, 0.01, ...0.99, 1]
}
}
}
or threshold: [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
, call back is not being triggered.
element sample:
<section v-waypoint="{ active: true, callback: onWaypoint, options: { wayPointOptions } }">
...
</section>
UPDATE
Adding threshold inline instead of data works fine 🤔
<section
v-waypoint="{
active: true,
callback: onWaypoint,
options: {
threshold: Array(101).join(0).split(0).map((n, i) => (i) / 100)
}
}"
>
...
</section>
I have 2 way points
<div id="StickyContainer" class="Carousel-wrapper" v-waypoint="{ active: true, callback: onWaypointWrapper }">
<div :class="{'is-sticky' : headerSticky}">
<CarouselHeader :titles="plans[0]" v-waypoint="{ active: true, callback: onWaypointHeader }" />
<div>....</div>
</div>
</div>
data() {
return {
headerSticky: false,
passStickyContainer: false
};
},
methods: {
onWaypointHeader({ going, direction }) {
console.log({going, direction});
if (going === "out" && direction === "top" && !this.passStickyContainer) {
this.headerSticky = true;
}
},
onWaypointWrapper({ going, direction }) {
console.log({going, direction});
if (going === "out" && direction === "top" && !this.passStickyContainer) {
this.headerSticky = false;
this.passStickyContainer = true;
}
}
}
I have a header that I want to make sticky and then when the container passes the top of the window I want to make the sticky go away. And when I scroll up again I want to make the header sticky.
Im changing the flag of the css and the item gets position static from position fixed and not by scrolling. But when I scroll the container up again I console log {going: "in", direction: "top"}
where as it should be {going: "in", direction: "bottom"}
. I dont why its not showing the right flag. But after I scroll up and down again it shows the right flags. Its right after when I remove the class and try to scroll up the container.
OK so I'll try not to butcher this explanation.
On waypoint I make an api call to return a list of items, then render them on page as a list or rows.
As long as the waypoint gets pushed off screen, then on scroll the waypoint is triggered and more data is fetched. But if the waypoint is not off screen this can never happen.
So this becomes a problem depending on screen height.
Lets say my api call is returning 3 items (small to expose the problem).
Lets also say my screen is tall enough to render 9 items.
What will happen is on page load we fetch the first three (as per my created()),
Then because of the waypoint being detected the first time it fetches an additional 3
We have 6 items on screen, which is not enough to push the waypoint off screen.
Because of this, infinite scroll breaks as there is no way to trigger any further waypoints.
Am I doing something wrong or is this a bug? The documentation seems simple enough where I think I have done what I should.
Now if I set the number of the results to something larger like 10 items, then waypoint works fine. Get's 10, pushes waypoint off screen, scroll, trigger, fetch, repeat.
However I guess I could argue that this same issue would happen if I had a very tall screen.
I could see how you wouldn't want to continually repeat this trigger if waypoint is on screen permanently (maybe youre at the end of the list / no more data). So I'm not sure how to propose reconciling both situations.
Using Safari Version 12.0.3 on Mac Os Mojave
TypeError: undefined is not a constructor (evaluating 'new window.IntersectionObserver(e,t)')
appear when I import the component below.
In every other browser that I tested works properly.
<template>
<div
v-waypoint="{
active: true,
callback: onComponentInViewport,
options: intersectionOptions,
}"
class="mask-displayer"
:class="{
fixed: isFixed,
}"
>
...
</template>
<script>
data() {
return{
displayFilter: false,
intersectionOptions: {
root: null,
rootMargin: '0px 0px 0px 0px',
threshold: [0.1, 0.75],
},
},
},
methods: {
onComponentInViewport({ going, direction }) {
// going: in, out
// direction: top, right, bottom, left
// && direction === this.$waypointMap.DIRECTION_TOP
if (going === this.$waypointMap.GOING_IN) {
// Going From Top
this.displayFilter = true
}
if (going === this.$waypointMap.GOING_OUT) {
// Going From Top
this.displayFilter = false
}
},
}
</script>
how to catch last callback for elements that appear on the screen ?
Is there a way to implement this.$waypointMap
on the Vue 3 version of waypoint?
I had used this on the Vue 2 version but doesn't look to be documented on the new one. I'm wanting to just add one class and disable the going and direction.
methods: { onWaypoint({ el, going, direction }) { if (going === this.$waypointMap.GOING_IN) { el.classList.add('waypoint') } }, },
i'm new on VueJS and i want install v-waypoint.js with vue2js it's doesn't work," I can not find this problem anywhere, if someone can help me, I'll be grateful, follow my html and js
<--------- main.js ----->
var App = require('./components/Example.vue')
Vue.component('v-waypoint', {
name:'app',
template: '
<--------- index.html ----->
<--------- Example.vue----->
When I include the component this way into a component of my app:
<template>
<div>some long content</div>
<Waypoint @change="onRead" :active="notYetRead"></Waypoint>
</template>
// This is composition API inside <script setup>
import { Waypoint } from "vue-waypoint"
const notYetRead = ref(true)
const onRead = (waypointState: "IN" | "OUT") => {
if (waypointState === "IN") {
console.log("seen")
notYetRead.value = false
}
}
The event never fires, and when the page loads I get several warnings by Vue:
[Vue warn]: onMounted is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement. runtime-core.esm-bundler.js:6584
[Vue warn]: onBeforeUpdate is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement. runtime-core.esm-bundler.js:6584
[Vue warn]: onUpdated is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement. runtime-core.esm-bundler.js:6584
[Vue warn]: onBeforeUnmount is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement. runtime-core.esm-bundler.js:6584
[Vue warn]: Missing ref owner context. ref cannot be used on hoisted vnodes. A vnode with ref must be created inside the render function.
My component loads and works fine if I remove Waypoint
.
I've just moved to vite for my front-end build tool and I'm getting this error:
Uncaught SyntaxError: The requested module {{ path }}/node_modules/vue-waypoint/dist/vue-waypoint.umd.min.js?v=545acbd4' does not provide an export named 'Waypoint'
Has something changed with Vue 3 or is there a declaration that I'm missing?
I have a long scrolling website, and there are several waypoints throughout. The waypoints work fine as i'm scrolling, but oftentimes when i'm testing a particular section, i'll refresh the page, the scroll position will persist ( on Chrome at least ), but the waypoint won't fire. To make it fire, i have to scroll 1 page up/down, and then back, to trigger the waypoint.
Could you possibly make the waypoint check it's position on initiation?
Ref: https://github.com/w3c/IntersectionObserver
Instead of vue-collision
Say i have three components in a parent component, i want to make those three child components load only when its visible in viewport. how can i do that?
I'm new on VueJS and i want to install v-waypoint.js with vue2js it's doesn't work," I can not find this problem anywhere, if someone can help me, I'll be grateful, follow my html and js. plenty of thanks in advance.
intersectionOptions: {
root: null,
rootMargin: '0px 0px 0px 0px',
thresholds: [0, 100]
} // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
According to the docs at the link provided, the above code's parameter, thresholds
, should be threshold
. That is the only thing that worked for me.
thresholds
is not known by the browser, but in my case it seemed to default threshold
to 1 even though the docs say it should default to 0
Also, threshold
seems to work only when the target element has a non zero height. I doubt it is a problem with this plugin but it may help any future users with a similar issue
Hi @scaccogatto
I'm using v-waypoints in a rendered list, and am having issues trying to access the parent element that holds each v-waypoint component with the attached handler, are there any simple ways to achieve this? -
this.$el //returns everything.
here's the template markup(pug):
section.hero-slide(v-for="(slide, index) in slides" :id="'hero-slide-' + (index + 1)")
v-waypoint#wp-1(@waypoint-in="heroIn(index)")
v-waypoint#wp-2(@waypoint-out="heroOut(index)")
article.hero-articles(@click="clickReport" :id="'hero-article-' + (index + 1)")
h2.waypoint-text {{slide.title}}
and the handler:
methods: {
heroIn (index, e) {
console.log('hero ' + index + ' in')
console.log(e.currentTarget)
console.log(this.$el)
},
heroOut (index) {
console.log('hero ' + index + ' out')
}
}
Is there support for this currently?
Hello, great plugin! thank you. I am having some difficulties with threshold. I have tried every scenario but can not get it to work. here is what it looks like:
How can I use offset
Hi. I got this from docs but this doesn't tell me how to use this plugin
<template>
<div class="waypoint-test">
<v-waypoint @waypoint-in="inHandler"
@waypoint-out="outHandler"></v-waypoint>
<div class="waypoint-text">
{{ text }}
</div>
</div>
</template>
<script>
import Vue from 'vue'
import VueWaypoint from 'vue-waypoint'
Vue.use(VueWaypoint)
export default {
data: () => {
return {
text: 'not-trigger-yet'
}
},
methods: {
inHandler () {
this.text = 'going in'
},
outHandler () {
this.text = 'going out'
}
}
}
</script>
It just says going in
in empty page.
Please explain how to use it.
something to preview the plugin, maybe under /docs
folder
There is a typo in defineDirective
function. It is update
hook function, not updated
See https://vuejs.org/v2/guide/custom-directive.html#Hook-Functions
I try use it in component in my project but it's doesn't work. I use 3.5.2 version.
Failed to resolve component: Waypoint
I'm having trouble getting this to build when working with Vue JS/Gridsome. I've wrapped the directive component in per the Gridsome documentation and also tried to import it into the mounted hook, but still getting the ReferenceError: window is not defined
<ClientOnly>
<div class="hiw-card" id="hiw-deliver"
v-waypoint="{active: true, callback: mobScroll, options: intersectionOptions }">
<h4>Deliver</h4>
<p>A customers’ data is available via conventional REST API, as well as via a digital wallet, as
frequently
as energy is read and CO2e offset/liability calculated (continuously), and as frequently as RECs are
accumulated in mWh bundles.
</p>
<b-row class="justify-content-center">
<b-col cols="3">
<i class="fas fa-database fa-3x hiw-icon"></i>
</b-col>
<b-col cols="3">
<i class="far fa-long-arrow-alt-right fa-3x hiw-icon"></i>
</b-col>
<b-col cols="3">
<i class="far fa-user fa-3x hiw-icon"></i>
</b-col>
</b-row>
</div>
</ClientOnly>
mounted () {
window.waypoint = require('vue-waypoint')
}
I am using vue-cli webpack, and when I trying to using prerender the project, it always get error.
WARNING: JavaScript error while prerendering: /home
ReferenceError: Can't find variable: Symbol
phantomjs://code/phantom-page-render.js:26 in onError
please help, thanks
<template>
<div>
<header>
<nav :class="{sticky:stickyActive}">
<div class="container">
<div class="row">
<img
v-if="!stickyActive"
src="../assets/logo-white.png"
alt="Omnifood Logo"
class="logo"
>
<img v-else src="../assets/logo.png" alt="Omnifood Logo" class="logo-black">
<ul class="main-nav">
<li>
<a href="#">Food Delivery</a>
</li>
<li>
<a href="#">How It Works</a>
</li>
<li>
<a href="#">Our Cities</a>
</li>
<li>
<a href="#">Sign Up</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="hero-text">
<h1>Goodbye junk food
<br>Hello super healthy meals
</h1>
<a href="#" class="bttn bttn-full">I'm hungry</a>
<a href="#" class="bttn bttn-ghost">Show me more</a>
</div>
</header>
<section
class="section-features"
v-waypoint="{active: true, callback: onWaypoint, options: intersectionOptions}"
>
<div class="container">
<div class="row">
<h2>get food fast — not fast food</h2>
<p
class="long-copy"
>Hello, we're Omnifood, your new premium food delivery service. We know you're always busy. No time for cooking. So let us take care of that, we're really good at it, we promise!</p>
</div>
<div class="row">
<div class="col-md-3 box">
<i class="ion-ios-infinite-outline icon-big"></i>
<h3>Up to 365 days/year</h3>
<p>Never cook again! We really mean that. Our subscription plans include up to 365 days/year coverage. You can also choose to order more flexibly if that's your style.</p>
</div>
<div class="col-md-3 box">
<i class="ion-ios-stopwatch-outline icon-big"></i>
<h3>Ready in 20 minutes</h3>
<p>You're only twenty minutes away from your delicious and super healthy meals delivered right to your home. We work with the best chefs in each town to ensure that you're 100% happy.</p>
</div>
<div class="col-md-3 box">
<i class="ion-ios-nutrition-outline icon-big"></i>
<h3>100% organic</h3>
<p>All our vegetables are fresh, organic and local. Animals are raised without added hormones or antibiotics. Good for your health, the environment, and it also tastes better!</p>
</div>
<div class="col-md-3 box">
<i class="ion-ios-cart-outline icon-big"></i>
<h3>Order anything</h3>
<p>We don't limit your creativity, which means you can order whatever you feel like. You can also choose from our menu containing over 100 delicious meals. It's up to you!</p>
</div>
</div>
</div>
</section>
<section class="section-meals">
<ul class="meals-showcase clearfix">
<li>
<figure class="meal-photo">
<img src="../assets/1.jpg" alt="1">
</figure>
</li>
<li>
<figure class="meal-photo">
<img src="../assets/2.jpg" alt="2">
</figure>
</li>
<li>
<figure class="meal-photo">
<img src="../assets/3.jpg" alt="3">
</figure>
</li>
<li>
<figure class="meal-photo">
<img src="../assets/4.jpg" alt="4">
</figure>
</li>
</ul>
<ul class="meals-showcase clearfix">
<li>
<figure class="meal-photo">
<img src="../assets/5.jpg" alt="5">
</figure>
</li>
<li>
<figure class="meal-photo">
<img src="../assets/6.jpg" alt="6">
</figure>
</li>
<li>
<figure class="meal-photo">
<img src="../assets/7.jpg" alt="7">
</figure>
</li>
<li>
<figure class="meal-photo">
<img src="../assets/8.jpg" alt="8">
</figure>
</li>
</ul>
</section>
.......
</template>
<script>
export default {
data: function() {
return {
intersectionOptions: {
root: null,
rootMargin: "0px 0px 0px 0px",
threshold: 0 // [0.25, 0.75] if you want a 25% offset!
}, // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
stickyActive: false,
mobileAppActive: false
};
},
methods: {
onWaypoint({ going, direction }) {
if (direction === this.$waypointMap.DIRECTION_TOP) {
this.stickyActive = true;
} else if (direction === this.$waypointMap.DIRECTION_BOTTOM) {
this.stickyActive = false;
}
},
onMobileAppLogo({ going, direction }) {
if (direction === this.$waypointMap.DIRECTION_TOP)
this.mobileAppActive = true;
}
}
};
</script>
Hi there,
I'm fairly new to vue.js and am just trying to see if I can use this for a project that requires some animation on scroll. The vue.js CLI was used to scaffold the project. I simply included the sample code you have in your readme, but keep getting a [Vue warn]: Failed to resolve directive: waypoint
in the console. Here's my component:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<div v-waypoint="{ active: true, callback: onWaypoint, options: intersectionOptions }"></div>
</div>
</template>
<script>
import Vue from 'vue'
import VueWaypoint from 'vue-waypoint'
// Waypoint plugin
Vue.use(VueWaypoint)
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to Your Vue.js App',
intersectionOptions: {
root: null,
rootMargin: '0px 0px 0px 0px',
thresholds: [0]
} // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
}
},
methods: {
onWaypoint ({ going, direction }) {
// going: in, out
// direction: top, right, bottom, left
if (going === this.$waypointMap.GOING_IN) {
console.log('waypoint going in!')
}
if (direction === this.$waypointMap.DIRECTION_TOP) {
console.log('waypoint going top!')
}
}
}
}
</script>
I may just be using Vue.use()
incorrectly? Please let me know if you have any tips!
Thanks for the wonderful component.
I tried to use this in nuxt application even surrounded by <no-ssr>
tag but I couldn't even import thew library as it throws window
object reference error. It would be a really help if you can modify this to work with nuxt applications (client side)
I am using a fresh setup of nuxt 3 and always get the error window is not defined
Full error message:
500
window is not defined
at callWithErrorHandling (C:\Users\USER\sites\nuxt3_test\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:156:18)
at setupStatefulComponent (C:\Users\USER\sites\nuxt3_test\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:7190:25)
at setupComponent (C:\Users\USER\sites\nuxt3_test\node_modules\@vue\runtime-core\dist\runtime-core.cjs.js:7151:36)
at renderComponentVNode (C:\Users\USER\sites\nuxt3_test\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:614:15)
at Module.ssrRenderComponent (C:\Users\USER\sites\nuxt3_test\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:86:10)
at _sfc_ssrRender (C:\Users\USER\sites\nuxt3_test\app.js:26:31)
at renderComponentSubTree (C:\Users\USER\sites\nuxt3_test\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:683:9)
at renderComponentVNode (C:\Users\USER\sites\nuxt3_test\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:631:12)
at Module.ssrRenderComponent (C:\Users\USER\sites\nuxt3_test\node_modules\@vue\server-renderer\dist\server-renderer.cjs.js:86:10)
package.json
{
"name": "nuxt-app",
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"devDependencies": {
"@nuxt/devtools": "latest",
"@types/node": "^18.17.3",
"nuxt": "^3.6.5"
},
"dependencies": {
"vue-waypoint": "^4.2.5"
}
}
I created the following file: plugins/vue-waypoint.client.js
. The .client
part should make sure it's run on client-side only
import { Waypoint } from "vue-waypoint";
export default defineNuxtPlugin((nuxtApp) => {
if (process.client) {
nuxtApp.vueApp.use(Waypoint);
}
});
And used your code from the documentation in my app.vue
<template>
<Waypoint @change="onChange">
<!-- anything you want here -->
</Waypoint>
</template>
<script lang="ts">
import { Waypoint } from "vue-waypoint";
export default defineComponent({
name: "SomeComponent",
components: {
Waypoint,
},
setup() {
const onChange = (waypointState) => {
// Going can be:
// IN
// OUT
console.log(waypointState.going);
// Direction can be:
// UP
// DOWN
// LEFT
// RIGHT
console.log(waypointState.direction);
};
return { onChange };
},
});
</script>
vue-waypoint/src/waypointInterface.js
Line 15 in 3fb1f63
In your example on how to use the library
data: () => ({ intersectionOptions: { root: null, rootMargin: '0px 0px 0px 0px', **thresholds**: [0] } // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API })
The parameter should be threshold, it won't trigger the waypoints on the desired thresholds (it will still fire when element reaches top of page)
Does this console.log serve any purpose beyond debugging:
vue-waypoint/src/intersectionObserver.js
Line 15 in c35c244
When using this module with more than a trivial amount of watchers it fills up most of my console history, which makes using it for other purposes very difficult. Hope this can at least be put behind some kind of flag.
Thanks!
Just installed and uninstalled because can't attach a data to the callback event...
I am wondering why you call this a "Vue plugins" if we can't attach data or components to the callback.
<template v-for="(event,index) in getEventsList">
<div class="ctn-message"
v-waypoint="{ active: true, callback: onScreen(event) }"
>{{event.content}}</div>
</template>
OR
<template v-for="(event,index) in getEventsList">
<div class="ctn-message"
v-waypoint="{ active: true, callback: onScreen, data:event}"
>{{event.content}}</div>
We need this...thanks.
does the callback function support custom param pass in?
Hi scaccogatto, I want to fire a function only once when an element is in the viewport. Therefore I'm trying to use VueWaypoint.removeObserver (Element el, function callback)
.
I assumed this would work:
isInViewport: function(event) {
// this is where I do stuff
VueWaypoint.removeObserver(event.el);
}
isInViewport
is succesfully triggered by Waypoint, but I'm getting a TypeError: t.unobserve is not a function
. I guess I oversee something. Can you help me out?
Hi! Looks like this plugin doesn't work well with Vue SSR. Getting a ReferenceError: window is not defined
error on compilation. Any thoughts on how to handle?
Hello,
Looking at bundle phobia, the gzipped bundle size went from 1.1kB to 40.4kB betrween version 3 and 4. Does that seem right?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.