{"id":13518788,"url":"https://github.com/ai/visibilityjs","last_synced_at":"2025-12-12T07:28:48.336Z","repository":{"id":44470741,"uuid":"1919264","full_name":"ai/visibilityjs","owner":"ai","description":"Wrapper for the Page Visibility API","archived":false,"fork":false,"pushed_at":"2024-01-11T16:41:43.000Z","size":307,"stargazers_count":1833,"open_issues_count":3,"forks_count":107,"subscribers_count":65,"default_branch":"master","last_synced_at":"2025-04-13T02:17:20.108Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ai.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2011-06-19T12:58:26.000Z","updated_at":"2025-04-10T10:20:22.000Z","dependencies_parsed_at":"2024-06-18T11:16:02.642Z","dependency_job_id":"9e7e33ac-01cb-42bb-9bdc-6750dbbe75fd","html_url":"https://github.com/ai/visibilityjs","commit_stats":{"total_commits":259,"total_committers":22,"mean_commits":"11.772727272727273","dds":0.09652509652509655,"last_synced_commit":"a1e126e79f670b89a8c74283f09ba54784c13d26"},"previous_names":["ai/visibility.js"],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fvisibilityjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fvisibilityjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fvisibilityjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Fvisibilityjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ai","download_url":"https://codeload.github.com/ai/visibilityjs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654104,"owners_count":21140237,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T05:01:49.114Z","updated_at":"2025-12-12T07:28:43.281Z","avatar_url":"https://github.com/ai.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","CoffeeScript"],"sub_categories":[],"readme":"# Visibility.js [![Build Status](https://travis-ci.org/ai/visibilityjs.svg)](https://travis-ci.org/ai/visibilityjs)\n\n\u003cimg align=\"right\" width=\"100\" src=\"./logo.svg\" title=\"Visibility.js logo by Eugenia Tuchapets\"\u003e\n\nVisibility.js is a wrapper for the [Page Visibility API]. It hides vendor prefixes and adds high level functions.\n\nPage Visibility API allows you to determine whether your web page is either visible to\na user or hidden in background tab or prerendering. It allows you to use\nthe page visibility state in JavaScript logic and improve browser performance\nby disabling unnecessary timers and AJAX requests, or improve user interface\nexperience (for example, by stopping video playback or slideshow when user\nswitches to another browser tab).\n\nMoreover, you can detect if the browser is just [prerendering] the page while\nthe user has still not opened the link, and don’t count this as a visit in your\nanalytics module, or do not run heavy calculations or other actions which will\ndisable the prerendering.\n\nPage Visibility API is [natively supported] by all browsers. For old browsers\nyou can use `lib/visibility.fallback.js` with focus/blur hack (note that this\nhack has an issue: when browser just lose focus but still visible for user, its state will change to [hidden]).\n\n\u003ca href=\"https://evilmartians.com/?utm_source=visibilityjs\"\u003e\n\u003cimg src=\"https://evilmartians.com/badges/sponsored-by-evil-martians.svg\" alt=\"Sponsored by Evil Martians\" width=\"236\" height=\"54\"\u003e\n\u003c/a\u003e\n\n[Page Visibility API]: http://www.w3.org/TR/page-visibility/\n[prerendering]:        http://code.google.com/chrome/whitepapers/prerender.html\n[natively supported]:  http://caniuse.com/pagevisibility\n\n## Translations\n\nДокументация на русском:\n[habrahabr.ru/blogs/javascript/125833/](http://habrahabr.ru/blogs/javascript/125833/)\n\n## States\n\nCurrently the Page Visibility API supports three visibility states:\n\n* `visible`: user has opened the page and works within it.\n* `hidden`: user has switched to another tab or minimized browser window.\n* `prerender`: browser is just prerendering a page which may possibly be opened\n   by the user to make the apparent loading time smaller.\n\n## Timers\n\nThe main use case for this library is to enable some of the times only when\ncontent is visible to the user, i.e. the ones animating a countdown animation.\n\n`Visibility.every(interval, callback)` is similar to\n`setInterval(callback, interval)`, but calls `callback` every `interval` ms only\nif the page is visible. For example, let’s create a countdown timer:\n\n```js\nVisibility.every(1000, function () {\n    updateCountdownAnimation();\n});\n```\n\nYou can provide an additional interval which will be used when the page\nis hidden. In next example, a check for inbox updates will be run every 1 minute\nfor a visible page and every 5 minutes for a hidden one:\n\n```js\nvar minute = 60 * 1000;\nVisibility.every(minute, 5 * minute, function () {\n    checkForEmail();\n});\n```\n\nWhen the page becomes visible, if the callback has not been called in longer than\nthe visible interval, it will be called immediately. In the example above, if you\nhid the page for 9 minutes, `checkForEmail` will get called once while the page is hidden,\nand immediately when it is made visible.\n\n`Visibility.every` returns a timer identifier, much like the `setInterval`\nfunction. However, it cannot be passed to `clearInterval`, and you should use\n`Visibility.stop(id)` to stop the timer.\n\n```js\nvar slideshow = Visibility.every(5 * 1000, function () {\n    nextSlide();\n});\n\n$('.stopSlideshow').click(function () {\n    Visibility.stop(slideshow);\n});\n```\n\nIf the browser does not support the Page Visibility API, `Visibility.every` will\nfall back to `setInterval`, and `callback` will be run every `interval` ms for\nboth the hidden and visible pages.\n\n## Initializers\n\nAnother common use case is when you need to execute some actions upon a switch to\nparticular visibility state.\n\n### Waiting until the page becomes visible\n\n`Visibility.onVisible(callback)` checks current state of the page. If it is\nvisible now, it will run `callback`, otherwise it will wait until state changes\nto `visible`, and then run `callback`.\n\nFor example, let’s show an animated notification only when the page is visible,\nso if some user opens a page in the background, the animation will delay until\nthe page becomes visible, i.e. until the user has switched\nto a tab with the page:\n\n```js\nVisibility.onVisible(function () {\n    startIntroAnimation();\n});\n```\n\nIf a browser doesn’t support Page Visibility API, `Visibility.onVisible`\nwill run the `callback` immediately.\n\n### Wait until the page is opened after prerendering\n\nA web developer can hint a browser (using Prerendering API) that an user\nis likely to click on some link (i.e. on a “Next” link in a multi-page article),\nand the browser then may prefetch and prerender the page, so that the user will\nnot wait after actually going via the link.\n\nBut you may not want to count the browser prerendering a page as a visitor in\nyour analytics system. Moreover, the browser will disable prerendering if you\nwill try to do heavy computations or use audio/video tags on the page. So, you\nmay decide to not run parts of the code while prerendering and wait until the\nuser actually opens the link.\n\nYou can use `Visibility.afterPrerendering(callback)` in this cases. For example,\nthis code will only take real visitors (and not page prerenderings) into\naccount:\n\n```js\nVisibility.afterPrerendering(function () {\n    Statistics.countVisitor();\n});\n```\n\nIf the browser doesn’t support Page Visibility API,\n`Visibility.afterPrerendering` will run `callback` immediately.\n\n## Low-level API\n\nIn some cases you may need more low-level methods. For example, you may want to\ncount the time user has viewed the page in foreground and time it has stayed in\nbackground.\n\n`Visibility.isSupported()` will return `true` if browser supports the\nPage Visibility API:\n\n```js\nif( Visibility.isSupported() ) {\n    Statistics.startTrackingVisibility();\n}\n```\n\n`Visibility.state()` will return a string with visibility state. More states\ncan be added in the future, so for most cases a simpler `Visibility.hidden()`\nmethod can be used. It will return `true` if the page is hidden by any reason.\nFor example, while prerendering, `Visibility.state()` will return `\"prerender\"`,\nbut `Visibility.hidden()` will return `true`.\n\nThis code will aid in collecting page visibility statistics:\n\n```js\n$(document).load(function () {\n\n    if ( 'hidden' == Visibility.state() ) {\n        Statistics.userOpenPageInBackgroundTab();\n    }\n    if ( 'prerender' == Visibility.state() ) {\n        Statistics.pageIsPrerendering();\n    }\n\n});\n```\n\nAnd this example will only enable auto-playing when the page is opening as a\nvisible tab (not a background one):\n\n```js\n$(document).load(function () {\n\n   if ( !Visibility.hidden() ) {\n       VideoPlayer.play();\n   }\n\n});\n```\n\nUsing `Visibility.change(callback)` you can listen to visibility state changing\nevents. The `callback` takes 2 arguments: an event object and a state name.\n\nLet’s collect some statistics with this events approach:\n\n```js\nVisibility.change(function (e, state) {\n    Statistics.visibilityChange(state);\n});\n```\n\nMethod `change` returns listener ID. You can use it to unbind listener by\n`Visibility.unbind(id)`:\n\n```js\nvar listener = Visibility.change(function (e, state) {\n    if ( !Visibility.hidden() ) {\n       VideoPlayer.pause();\n    }\n});\n\nVideoPlayer.onFinish(function () {\n    Visibility.unbind(listener);\n});\n```\n\nMethods `onVisible` and `afterPrerendering` will also return listener ID,\nif they wait visibility state changes. If they execute callback immediately,\nthey return `true` if Page Visibility API is supported and `false`\nif they can’t detect visibility state.\n\n```js\nvar listener = Visibility.onVisible(function () {\n    notification.takeAttention();\n});\n\nnotification.onOutOfDate(function () {\n    if ( typeof(listener) == 'number' ) {\n        Visibility.unbind(listener);\n    }\n});\n```\n\n## Packages\n\nVisibility.js is shipped with 4 files:\n\n* `visibility.core` – core module.\n* `visibility.timers` – `every` and `stop` methods to set `setInterval` depend\n  on visibility state.\n* `visibility` – `visibility.core` and `visibility.timers` together.\n* `visibility.fallback` – fallback for browser without Page Visibility API.\n  It use document `focus`/`blur` events, so document become to be hidden,\n  when browser just lose focus, but still visible for user.\n\n## Installing\n\nAvailable by [NPM](https://www.npmjs.com/package/visibilityjs):\n\n```\nnpm install --save visibilityjs\n```\n\n## Contributing\n\n1. To run tests you need node.js and npm. For example, in Ubuntu run:\n\n   ```sh\n   sudo apt-get install nodejs npm\n   ```\n\n2. Next install npm dependencies:\n\n   ```sh\n   npm install\n   ```\n\n3. Run all tests:\n\n   ```sh\n   npm test\n   ```\n\n4. Also you can see real usage example in integration test\n   `test/integration.html`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fai%2Fvisibilityjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fai%2Fvisibilityjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fai%2Fvisibilityjs/lists"}