Detect when an element is becoming visible or hidden on the page.

Overview

vue-observe-visibility logo

vue-observe-visibility

Detect when an element is becoming visible or hidden on the page. Demo

Become a Patreon

Sponsors

sponsors logos


Table of contents

Installation

npm install --save vue-observe-visibility

⚠️ This plugin uses the Intersection Observer API that is not supported in every browser (currently supported in Edge, Firefox and Chrome). You need to include a polyfill to make it work on incompatible browsers.

Import

import Vue from 'vue'
import VueObserveVisibility from 'vue-observe-visibility'

Vue.use(VueObserveVisibility)

Or:

import Vue from 'vue'
import { ObserveVisibility } from 'vue-observe-visibility'

Vue.directive('observe-visibility', ObserveVisibility)

Browser

<script src="vue.js"></script>
<script src="https://unpkg.com/vue-observe-visibility/dist/vue-observe-visibility.min.js"></script>

The plugin should be auto-installed. If not, you can install it manually with the instructions below.

Install all the directives:

Vue.use(VueObserveVisibility)

Use specific directives:

Vue.directive('observe-visibility', VueObserveVisibility.ObserveVisibility)

Usage

The v-observe-visibility directive is very easy to use. Just pass a function as the value:

<div v-observe-visibility="visibilityChanged">

This also works on components:

<MyComponent v-observe-visibility="visibilityChanged" />

The function will be called whenever the visiblity of the element changes with the argument being a boolean (true means the element is visible on the page, false means that it is not).

The second argument is the corresponding IntersectionObserverEntry object.

visibilityChanged (isVisible, entry) {
  this.isVisible = isVisible
  console.log(entry)
}

IntersectionObserver options

It's possible to pass the IntersectionObserver options object using the intersection attribute:

<div v-observe-visibility="{
  callback: visibilityChanged,
  intersection: {
    root: ...,
    rootMargin: ...,
    threshold: 0.3,
  },
}">

Once

It can be useful to listen for when the element is visible only once, for example to build introduction animations. Set the once option to true:

<div v-observe-visibility="{
  callback: visibilityChanged,
  once: true,
}">

Throttling visibility

You can use the throttle options (in ms) specifying minimal state duration after which an event will be fired. It's useful when you are tracking visibility while scrolling and don't want events from fastly scrolled out elements.

<div v-observe-visibility="{
  callback: visibilityChanged,
  throttle: 300,
}">

You can also pass a leading option to trigger the callback the first time when the visibility changes without waiting for the throttle delay. I can either be visible, hidden or both.

<div v-observe-visibility="{
  callback: visibilityChanged,
  throttle: 300,
  throttleOptions: {
    leading: 'visible',
  },
}">

Passing custom arguments

You can add custom argument by using an intermediate function:

<div v-observe-visibility="(isVisible, entry) => visibilityChanged(isVisible, entry, customArgument)">

Here visibilityChanged will be call with a third custom argument customArgument.

Disabling the observer

Passing a falsy value to the directive will disable the observer:

<div
  v-for="(item, index) of items"
  :key="item.id"
  v-observe-visibility="index === items.length - 1 ? visibilityChanged : false"
>

Example

<div id="app">
  <button @click="show = !show">Toggle</button>
  <label>
    <input type="checkbox" v-model="isVisible" disabled/> Is visible?
  </label>
  <div ref="test" v-show="show" v-observe-visibility="visibilityChanged">Hello world!</div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    show: true,
    isVisible: true,
  },
  methods: {
    visibilityChanged (isVisible, entry) {
      this.isVisible = isVisible
      console.log(entry)
    },
  },
})
</script>

License

MIT

Comments
  • How to use in Vue3 ? (rc.2)

    How to use in Vue3 ? (rc.2)

    Yes, I know Vue3 is not released yet. But 1. you will have to support it anyway very soon, 2. what about being the very first visibility observing component to support it?

    I tried the following in main.js:

    import { createApp } from 'vue'
    import App from './App.vue'
    import VueObserveVisibility from 'vue-observe-visibility'
    
    const app = createApp(App)
    app.component('observe-visibility', VueObserveVisibility)
    app.mount('#app')
    

    Also tried app.directive('observe-visibility', VueObserveVisibility.ObserveVisibility)instead of the component line. In both cases it gets compiled and runs with no errors but the callback is not called when the div is scrolled in/out of view.

    What I am doing wrong? / If it is not supposed to work under Vue3 what is the cause. Thank you.

    opened by cimpok 13
  • fix observer null issue

    fix observer null issue

    After several routing, I saw some element occur null exception on $nextTick. So I added checking logic for observer null or not. if ovserver is null, call estoryObserver().

    opened by onmylife 9
  • Occasionally misses an intersection taking place

    Occasionally misses an intersection taking place

    Hi,

    We are checking out the directive and were wondering if you are occasionally finding it 'misses' something arriving in the viewport until it is scrolled off the screen and back on again. We are looking in to what might cause it and will submit further if we find a bug ourselves, but have you had any experience of this before? Speed of scrolling does not seem to make a difference.

    Thanks for any advice you can give,

    Ben

    opened by bengallienne 4
  • Fix the rendering issue with ssr load

    Fix the rendering issue with ssr load

    We are using this plugin to load the images only when it enters the viewport, which worked fine in non ssr mode. However, when we refreshed the page the images in the viewport was not loaded on first load. It did load when we scrolled back and forth. This issue was seen in the Chrome browser version 77.

    I've made some code changes to fix this issue. Request you to review the pull request.

    opened by sirish-amatya 3
  • check if observer is not null

    check if observer is not null

    fixes cannot read property of 'observe' of null we get from time to time. The handle is somehow destroyed before nextTick is called, and then it's null which causes this error. Simple check if observer is still defined before doing "observe()" fixes it.

    opened by simllll 3
  • `rootMargin` has no effect

    `rootMargin` has no effect

    Greetings, I have a small problem related to rootMargin. I have a lazy image component:

    <img
      :src="loadedSrc"
      v-observe-visibility="{
        rootMargin,
        callback: handleVisibilityChange,
      }"
      class="base-image"
    >
    

    where rootMargin is a computed property related to a component height:

    ...
    computed: {
      rootMargin() {
        const { rootMarginBottom } = this;
        return `0px 0px ${rootMarginBottom}px 0px`;
      },
    },
    mounted() {
      const { $el } = this;
      this.$nextTick(() => {
        this.rootMarginBottom = $el.getBoundingClientRect().height * 3;
      });
    }
    ...
    

    The problem is that rootMargin has no effect on when callback is toggled. It is always when element is fully in the viewport. As you may guess I'm trying to preload image before it enters a viewport.

    It also works exactly the same way if i hardcode the rootMargin. It feels like its ignored...

    Can some one give me a hint where the problem is?

    Thank you in advance!

    opened by b12k 3
  • Infinite loop

    Infinite loop

    If I use this, then I run into infinite loop when it pushes value to array.

    addIndex (isVisible, entry, i) {
          if (isVisible) {
            this.indicesInViewPort.push(i)
          } 
        }
    

    This fires even if I don't scroll at all!

    opened by ChrisRobston 3
  • error after import

    error after import

    vue 2 with webpack 2

    yarn add intersection-observer vue-observe-visibility
    
    import 'intersection-observer'
    import VueObserveVisibility from 'vue-observe-visibility'
    // or import {VueObserveVisibility} from 'vue-observe-visibility'
    

    then

    error  in ./~/vue-observe-visibility/index.js
    
    Module parse failed: ~/Projects/js/revel/node_modules/vue-observe-visibility/index.js Unexpected token (1:20)
    You may need an appropriate loader to handle this file type.
    | export default from './dist/vue-observe-visibility'
    | export * from './dist/vue-observe-visibility'
    | import './dist/vue-observe-visibility.css'
    
     @ ./src/main.js 12:0-62
     @ multi ./build/dev-client ./src/main.js
    

    Anything else I missed?

    opened by leopku 3
  • Instructions for using with Vue3

    Instructions for using with Vue3

    Hi,

    Trying to use vue-observe-visilibility in a vue3 using v2.0.0-alpha.1. No errors but it doesn't call the callback.

    Am I using it correctly?

    main.js

    import { createApp } from 'vue';
    import VueObserveVisibility from 'vue-observe-visibility'
    import App from './App.vue';
    
    const app = createApp(App);
    app.use(VueObserveVisibility);
    app.mount('#app');
    

    component.js

    <template>
      <ChildComponent
          v-observe-visibility="{
            callback: (isVisible, entry) => alert("visible"),
            throttle: 300,
            intersection: {
              0.8,
            },
    
      />
    </template>
    
    need-repro 
    opened by tomeraz 2
  • Simplify threshold type check

    Simplify threshold type check

    Simplify threshold type check: the typeof this.options.intersection.threshold === 'number' check already covers the intent of the this.options.intersection check

    opened by dhritzkiv 2
  • Restore support for Array treshold values

    Restore support for Array treshold values

    Sorry about my linter, but I want you to check it out and let me know if it's good. The real change is in here:

    https://github.com/Akryum/vue-observe-visibility/pull/215/files#diff-a67c202fecb3c85d20b37a10185efc1bR60

    opened by iosamuel 2
  • fix: threshold array callback

    fix: threshold array callback

    If the Threshold is an Array we cannot check for ´entry.intersectionRatio >= this.threshold´ because it will always be false, so the callback is not executed correctly. We need to call it if it finds an intersection with the array that we provided.

    opened by iosamuel 0
  • fix: threshold array callback

    fix: threshold array callback

    If the Threshold is an Array we cannot check for ´entry.intersectionRatio >= this.threshold´ because it will always be false, so the callback is not executed correctly. We need to call it if it finds an intersection with the array that we provided.

    opened by iosamuel 0
  • Add option to disable for tests

    Add option to disable for tests

    I have a setup where I'm using Jest and vue-test-utils to mount and test my components. Some of the inner components use the v-observe-visibility directive. However, it breaks/slows down considerably the tests. It looks like it really doesn't like being run in testing virtual DOM. I got around this by adding:

    Vue.prototype.isTest = process.env.JEST_WORKER_ID !== undefined

    in my startup config. And then a

    v-observe-visibility="isTest ? false : onRulesVisible" i

    nside my components. However, this feels very clunky. It'd be nice if there were a hook we could access to disable the directive when running tests. I'll admit, I haven't taken a look at the inner workings of the directive. I can't be the only one who has run into this problem.

    opened by gabaum10 0
  • build(deps-dev): bump nodemon from 1.19.4 to 2.0.12

    build(deps-dev): bump nodemon from 1.19.4 to 2.0.12

    Bumps nodemon from 1.19.4 to 2.0.12.

    Release notes

    Sourced from nodemon's releases.

    v2.0.12

    2.0.12 (2021-07-10)

    Bug Fixes

    • windows: properly handle quoted args in event (0823f18), closes #1823

    v2.0.11

    2.0.11 (2021-07-09)

    Bug Fixes

    • ensure numerical OS version check (f523d0e)

    v2.0.10

    2.0.10 (2021-07-08)

    Bug Fixes

    • windows 8 doesn't support windows-kill (6c6cb65), closes #1876

    v2.0.9

    2.0.9 (2021-06-30)

    Bug Fixes

    v2.0.8

    2.0.8 (2021-06-29)

    Bug Fixes

    v2.0.7

    2.0.7 (2021-01-06)

    Bug Fixes

    ... (truncated)

    Commits
    • 0823f18 fix(windows): properly handle quoted args in event
    • b52fc89 Merge branch 'master' of github.com:remy/nodemon
    • f523d0e fix: ensure numerical OS version check
    • 46791d6 chore: update issue template
    • 79ad546 chore: fix stale.yml
    • 08f6599 chore: move workflow to dir
    • f3903a4 chore: update stalebot
    • 6c6cb65 fix: windows 8 doesn't support windows-kill
    • 5bb92d4 Merge branch 'master' of github.com:remy/nodemon
    • f4b89f5 chore: new supporters
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language
    • @dependabot badge me will comment on this PR with code to add a "Dependabot enabled" badge to your readme

    Additionally, you can set the following in your Dependabot dashboard:

    • Update frequency (including time of day and day of week)
    • Pull request limits (per update run and/or open at any time)
    • Automerge options (never/patch/minor, and dev/runtime dependencies)
    • Out-of-range updates (receive only lockfile updates, if desired)
    • Security updates (receive only security updates, if desired)
    dependencies 
    opened by dependabot-preview[bot] 0
  • build(deps): [security] bump browserslist from 4.16.0 to 4.16.6

    build(deps): [security] bump browserslist from 4.16.0 to 4.16.6

    Bumps browserslist from 4.16.0 to 4.16.6. This update includes a security fix.

    Vulnerabilities fixed

    Sourced from The GitHub Security Advisory Database.

    Regular Expression Denial of Service in browserslist The package browserslist from 4.0.0 and before 4.16.5 are vulnerable to Regular Expression Denial of Service (ReDoS) during parsing of queries.

    Affected versions: >= 4.0.0 < 4.16.5

    Changelog

    Sourced from browserslist's changelog.

    4.16.6

    • Fixed npm-shrinkwrap.json support in --update-db (by Geoff Newman).

    4.16.5

    • Fixed unsafe RegExp (by Yeting Li).

    4.16.4

    • Fixed unsafe RegExp.
    • Added artifactory support to --update-db (by Ittai Baratz).

    4.16.3

    • Fixed --update-db.

    4.16.2

    4.16.1

    • Fixed Chrome 4 with mobileToDesktop (by Aron Woost).

    4.16

    • Add browserslist config query.

    4.15

    • Add TypeScript types (by Dmitry Semigradsky).

    4.14.7

    • Fixed Yarn Workspaces support to --update-db (by Fausto Núñez Alberro).
    • Added browser changes to --update-db (by @​AleksandrSl).
    • Added color output to --update-db.
    • Updated package.funding to have link to our Open Collective.

    4.14.6

    • Fixed Yarn support in --update-db (by Ivan Storck).
    • Fixed npm 7 support in --update-db.

    4.14.5

    • Fixed last 2 electron versions query (by Sergey Melyukov).

    4.14.4

    • Fixed Unknown version 59 of op_mob error.

    4.14.3

    • Update Firefox ESR.

    4.14.2

    • Fixed --update-db on Windows (by James Ross).
    • Improved --update-db output.

    4.14.1

    • Added --update-db explanation (by Justin Zelinsky).

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language
    • @dependabot badge me will comment on this PR with code to add a "Dependabot enabled" badge to your readme

    Additionally, you can set the following in your Dependabot dashboard:

    • Update frequency (including time of day and day of week)
    • Pull request limits (per update run and/or open at any time)
    • Automerge options (never/patch/minor, and dev/runtime dependencies)
    • Out-of-range updates (receive only lockfile updates, if desired)
    • Security updates (receive only security updates, if desired)
    dependencies security 
    opened by dependabot-preview[bot] 0
Releases(v2.0.0-alpha.1)
  • v2.0.0-alpha.1(Dec 28, 2020)

  • v1.0.0(Dec 28, 2020)

  • v0.4.6(Oct 23, 2019)

  • v0.4.5(Oct 20, 2019)

    New

    • throttle leading options, closes #113

    You can also pass a leading option to trigger the callback the first time when the visibility changes without waiting for the throttle delay. I can either be visible, hidden or both.

    <div v-observe-visibility="{
      callback: visibilityChanged,
      throttle: 300,
      throttleOptions: {
        leading: 'visible',
      },
    }">
    

    Fixed

    • SSR: Fix the rendering issue with ssr load #148
    Source code(tar.gz)
    Source code(zip)
  • v0.4.4(May 6, 2019)

  • v0.4.3(Oct 4, 2018)

    New

    • once option, closes #11. This is useful to create one-time animations as soon as the element becomes visible!

    Improved

    • add typings (#29)

    Fixed

    • deepEqual issue

    In previous releases:

    • uncesseray re-creation of observer, fixes #24
    • #22 cannot read property 'bind' of undefined
    • #18 threshold undefined
    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(May 28, 2018)

  • v0.3.1(Sep 18, 2017)

Owner
Guillaume Chau
Web & JavaScript enthusiast, @vuejs core team.
Guillaume Chau
trigger functions and events based on the element position on the screen

VueWaypoint trigger functions based on elements' positions, based on viewport Demo demo page Installation npm $ npm install vue-waypoint --save-dev Vu

Marco 'Gatto' Boffo 455 Dec 16, 2022
🔲 Vue directive to react on clicks outside an element without stopping the event propagation

v-click-outside Vue directive to react on clicks outside an element without stopping the event propagation. Great for closing dialogues and menus amon

Nicolas Del Valle 930 Dec 27, 2022
Vue 2.x directive to help a specified element listen for specific events occurring outside of itself.

vue-outside-events Vue 2.x directive to react on events outside of an element without stopping the event's propagation. Works well for handling clicks

Nicholas Hutchind 56 May 9, 2022
Vue V2 directive to react on clicks outside an element.

v-click-outside-x Vue V2 directive to react on clicks outside an element. Install $ npm install --save v-click-outside-x $ yarn add v-click-outside-x

Graham Fairweather 86 Aug 27, 2022
Detect when an element is becoming visible or hidden on the page.

vue-observe-visibility Detect when an element is becoming visible or hidden on the page. Demo Sponsors Table of contents Installation Usage Example In

Guillaume Chau 1.6k Dec 27, 2022
Detect when an element is becoming visible or hidden on the page.

vue-observe-visibility Detect when an element is becoming visible or hidden on the page. Demo Sponsors Table of contents Installation Usage Example In

Terminalqo 0 Oct 27, 2020
Vue Scroll Detect - Detect component visibility change on scrolling

Vue Scroll Detect Detect component visibility change on scrolling. Installation yarn add vue-scroll-detect Example See examples/ at Code Sandbox Usage

Dzul Nizam 1 Jun 5, 2022
vue lazy container,By detect the visibility of elements in the page, decide whether to load resources and render.

vue lazy container,By detect the visibility of elements in the page, decide whether to load resources and render.

null 5 Sep 25, 2022
Detect DOM element resizing based on Vue3.x

Detect DOM element resizing based on Vue3.x

null 0 Jul 22, 2021
A Vue.js component for detecting when components are visible in the viewport via the Vue.js scoped slots api.

vue-scrollview ScrollView is a Vue.js plugin that includes a set of components and methods for facilitating UI interactions tied to scrolling in your

Chris Hurlburt 115 Jun 28, 2022
v-visible directive for VueJS

VueVisible v-visible directive for VueJS (2.x) Demo A jsFiddle live demo: https://jsfiddle.net/fcpc6utm/ About This plugins adds a v-visible directive

Javis V. Pérez 31 May 8, 2021
Polyfill for `:focus-visible`

Based on the proposed CSS :focus-visible pseudo-selector, this prototype adds a focus-visible class to the focused element, in situations in which the

Web Incubator CG 1.6k Jan 3, 2023
✨ Automagically manage the visibility of :focus states in your app — by recreating the :focus-visible pseudo-selector behaviour.

✨ Automagically manage the visibility of :focus states in your app — by recreating the :focus-visible pseudoselector behaviour. Supports Vue 3.x out of the box ??

Fabian Beer 5 Jan 29, 2022
A Vue.js directive helps track visible elements.

vue-visibility-track A Vue.js directive helps track elements's visibility. Installing Using npm: npm install --save vue-visibility-track Using yarn: y

Xiaolin Wu 0 Mar 26, 2021
🚀🚀🚀vue3,vue3.0,vue,vue3.x,vue.js,vue后台管理,admin,vue-admin,vue-element-admin,ant-design,vue-admin-beautiful-pro,vab admin pro,vab admin plus主线版本基于element-plus、element-ui、ant-design-vue三者并行开发维护,同时支持电脑,手机,平板,切换分支查看不同的vue版本,element-plus版本已发布(vue3,vue3.0,vue,vue3.x,vue.js)

??????vue3,vue3.0,vue,vue3.x,vue.js,vue后台管理,admin,vue-admin,vue-element-admin,ant-design,vue-admin-beautiful-pro,vab admin pro,vab admin plus主线版本基于element-plus、element-ui、ant-design-vue三者并行开发维护,同时支持电脑,手机,平板,切换分支查看不同的vue版本,element-plus版本已发布(vue3,vue3.0,vue,vue3.x,vue.js)

good luck 13.4k Jan 1, 2023
BEEP Account Security Scanner - Detect if your credentials have been compromised (Vue + Ionic)

Beep: mobile account vulnerability scanner Every day, over 4 million online data records are stolen or lost. Beep tells you if your online accounts ha

Modus Create 154 Dec 2, 2022
A Vue.js plugin to detect idle/non-active users

v-idle Getting started V-idle is a Vue.js plugin to detect idle/non-active users. Installation Using NPM: npm install v-idle --save Basic usage Vue.js

Lukasz Malek 61 Dec 23, 2022
:electric_plug: Simple VueJS component to detect offline & online changes.

V-Offline ⚡ Detect offline & online events for your vue app. This is on GitHub so let me know if I've b0rked it somewhere, give me a star ⭐ if you lik

Vinayak Kulkarni 356 Dec 23, 2022
Vue directive to detect resize events with deboucing and throttling capacity.

Vue.resize Vue directive to detect HTML resize events based on CSS Element Queries with debouncing and throttling capacity. Demo Typical usage Simple

David Desmaisons 323 Dec 27, 2022
Vue directive to detect resize events with deboucing and throttling capacity.

Vue.resize Vue directive to detect HTML resize events based on CSS Element Queries with debouncing and throttling capacity. Demo Typical usage Simple

David Desmaisons 323 Dec 27, 2022