- Notifications
You must be signed in to change notification settings - Fork24
A Svelte action that monitors an element enters or leaves the viewport.🔥
License
svelte-inview/svelte-inview
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A Svelte action that monitors an element enters or leaves the viewport/parent element. Performant and efficient thanks to usingIntersection Observer under the hood. Can be used in multiple projects including lazy loading images, infinite scrolling, playing/pausing the video when in the viewport, tracking user behaviour firing link pre-fetching and animations and many many more.
🔥 Check it out livehere
- 👓️ Watch for any element that enters or leaves the viewport (or another wrapper/parent element).
- 🏎️ Thanks to usingIntersection Observer, Svelte Inview is blazing fast and doesn't block the main thread.
- 📦️ Tiny, yet powerful (just ~2kb). No external dependencies (well, apart from Svelte).
- 🎛️ Use it in several different scenarios such as lazy loading images, infinite scrolling, playing/pausing the video when in the viewport, firing link pre-fetching, animations and many many more.
- 🐥 Easy to use API.
↕️ Detects the scrolling direction.
The only thing you need is Svelte itself.
Svelte Inview is distributed vianpm.
$ yarn add svelte-inview# or$ npm install --save svelte-inview
⚠️ Modern browsers have the full support of Intersection Observer, but if you need to support ones like IE you can use thissimple polyfill. Just install it and import it in your project.
This is the most basic use case forsvelte-inview. Just add the action to the element you want to track -use:inview. You can also pass otherconfiguration props. You can see if the element is visible by checking theinView or from the inside of the callback method -on:inview_change.
<scriptlang="ts">import{inview}from'svelte-inview'; letisInView:boolean;constoptions={};</script><divuse:inview={options}on:inview_change={(event) => { const { inView, entry, scrollDirection, observer, node} = event.detail; isInView = inView; }} on:inview_enter={(event) => { const { inView, entry, scrollDirection, observer, node} = event.detail; isInView = inView; }} on:inview_leave={(event) => { const { inView, entry, scrollDirection, observer, node} = event.detail; isInView = inView; }} on:inview_init={(event) => { const { observer, node } = event.detail; }}>{isInView ? 'Hey I am in the viewport' : 'Bye, Bye'}</div>
Svelte Inview lets you easily lazy load images. For a better UX we can pass arootMargin="50px" props, so the image will be loaded when scroll is 50px before the viewport. After it appears in the viewport, you don't want to observe it anymore, hence theunobserveOnEnter props set to true.
<scriptlang="ts">import{inview}from'svelte-inview';importtype{ObserverEventDetails,Options}from'svelte-inview';letisInView;constoptions:Options={rootMargin:'50px',unobserveOnEnter:true,};consthandleChange=({ detail}:CustomEvent<ObserverEventDetails>)=>(isInView=detail.inView);</script><divuse:inview="{options}"on:inview_change="{handleChange}"> {#if isInView}<imgsrc="path/to/image.jpg"/> {:else}<divclass="placeholder"/> {/if}</div>
You can play/pause a video when it's in/out of the viewport. Simply pass correct methods inon:inview_enter andon:inview_leave callbacks.
<scriptlang="ts">import{inview}from'svelte-inview';importtype{ObserverEventDetails}from'svelte-inview'; letisInView:boolean; letvideoRef:HTMLElement;</script><divuse:inviewon:inview_enter={() => videoRef.play()} on:inview_leave={() => videoRef.pause()}><videowidth="500"controlsbind:this={videoRef}><sourcesrc="path/to/video.mp4"type="video/mp4"/></video></div>
You can also add some cool animations when an element enters the viewport. To make sure the animation won't fire too soon you can pass a negative value torootMargin. WheninView is true, add an animation class to your target. Additionally, you can detect the scroll direction to make the animations even cooler!
<scriptlang="ts">import{inview}from'svelte-inview';importtype{ObserverEventDetails,ScrollDirection,Options}from'svelte-inview'; letisInView:boolean; letscrollDirection:ScrollDirection;constoptions:Options={rootMargin:'-50px',unobserveOnEnter:true,};consthandleChange=({ detail}:CustomEvent<ObserverEventDetails>)=>{isInView=detail.inView;scrollDirection=detail.scrollDirection.vertical;};</script><divuse:inview={options}on:inview_change={handleChange}><divclass:animate={isInView}class:animateFromBottom={scrollDirection === 'down'} class:animateFromTop={scrollDirection === 'up'}> Animate me!</div></div>
Version 4 introduces new names for events. Before they were'change' | 'leave' | 'enter' | 'init'. In version 4 they're changed to'inview_change' | 'inview_leave' | 'inview_enter' | 'inview_init'.
This change was needed to satisfy Typescript, as the package was messing up the default types coming from svelte typings.To ensure backward compatibility, the original events names will still work for some time, but they won't be properly recognized by Typescript.To sum up, this will still work, but TS won't be happy about it:
on:change={(event)=>{const{ inView, entry, scrollDirection, observer, node}=event.detail;isInView=inView;}}
To make sure it works properlyand satisfy TS you'll need to change it to this:
on:inview_change={(event)=>{const{ inView, entry, scrollDirection, observer, node}=event.detail;isInView=inView;}}
Version 2 was returningobserve andunobserve methods on the events. In version 3 they were removed, and theobserver andnode are being returned instead. So if you used those methods before like this:
event.detail.observe(node);
You'll need to change it to:
event.detail.observer.observe(node);
Version 1 was using anInview component. In version 2 that was changed toaction - API is easier to consume, plus the obsolete wrapper is not longer needed. If you still want to use the component,check the documentation for version 1.
| Name | Type | Default | Description | Required |
|---|---|---|---|---|
| options.root | HTMLElement | window | The element that is used as the viewport for checking visibility of the target. Must be the ancestor of the target. | false |
| options.rootMargin | string | 0px | Margin around the root element. Values similar to the CSS margin property, e.g. "10px 20px 30px 40px". Can also be a percentage.See more. | false |
| options.threshold | number ornumber[] | 0 | Either a single number or an array of numbers which indicate at what percentage of the target's visibility the observer's callback should be executed. If you only want to detect when visibility passes the 50% mark, you can use a value of 0.5. If you want the callback to run every time visibility passes another 25%, you would specify the array [0, 0.25, 0.5, 0.75, 1]. The default is 0 (meaning as soon as even one pixel is visible, the callback will be run) | false |
| options.unobserveOnEnter | boolean | false | If true, target element stops being observed after the first time it appears in the viewport. Can be used when you want to fire the callback only once. | false |
| on:inview_change | function | - | Event fired every time the target element meets the specified threshold. Receivesevent object as an argument. Inside ofevent.detail you can find all the arguments specifiedhere. | false |
| on:inview_enter | function | - | Event fired every time the target element enters the viewport. Receivesevent object as an argument. Inside ofevent.detail you can find all the arguments specifiedhere . | false |
| on:inview_leave | function | - | Event fired every time the target element leaves the viewport. Receivesevent object as an argument. Inside ofevent.detail you can find all the arguments specifiedhere . | false |
| on:inview_init | function | - | Event fired on action initialization, before the observer starts observing the element. Receives lifecycle arguments specifiedhere | false |
| Name | Type | Description |
|---|---|---|
| inView | boolean | Visibility state of the target element. If it'strue, target passed at least the value of thethreshold props. |
| entry | IntersectionObserverEntry | Intersection Observer entry object generated every time when IO callback is fired. |
| scrollDirection.vertical | up ordown | Vertical scrolling direction. |
| scrollDirection.horizontal | left orright | Horizontal scrolling direction. |
| node | HTMLElement | Element that is being observed |
| observer | IntersectionObserver | Intersection Observer instance for the observed element. Among others, it allows to "turn off" the observer at the very beginning. |
| Name | Type | Description |
|---|---|---|
| node | HTMLElement | Element that is being observed |
| observer | IntersectionObserver | Intersection Observer instance for the observed element. Among others, it allows to "turn off" the observer at the very beginning. |
If you want to increase or decrease the area of the root, just pass therootMargin. On the image below you can see the blue area being theroot. It means that every time, the target element will enter or leave that area (or meet the specified threshold), a callback will be fired.
Distributed under the MIT License. SeeLICENSE for more information.
Maciek Grzybek -@grzybek_maciek -maciekgrzybek1@gmail.com -www.maciekgrzybek.dev
About
A Svelte action that monitors an element enters or leaves the viewport.🔥
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors8
Uh oh!
There was an error while loading.Please reload this page.


