├── .babelrc ├── .gitignore ├── README.md ├── change-title-onleave.js ├── change-title-onleave.min.js ├── index.js ├── media └── example.gif └── package.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"], 3 | "plugins": ["transform-es2015-modules-umd"] 4 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *log* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## change-title-onleave 2 | 3 | > Change the tab title on change its visibility 4 | 5 | # ![change-title-onleave](media/example.gif) 6 | 7 | ### Install 8 | 9 | You can get it on npm/yarn. 10 | 11 | ``` 12 | npm install change-title-onleave --save 13 | ``` 14 | 15 | If you're not into package management, [download a ZIP file](https://github.com/alisonmonteiro/change-title-onleave/archive/master.zip). 16 | 17 | ### Usage 18 | 19 | ```html 20 | 21 | ``` 22 | 23 | Now, you need to instantiate it by passing an object as parameter; 24 | 25 | ```js 26 | const options = {title: 'Hey! 👀', timeout: 1}; 27 | new ChangeTitleOnLeave(options); 28 | ``` 29 | 30 | You can also `require` it: 31 | 32 | ```js 33 | const changeTitle = require('change-title-onleave'); 34 | ``` 35 | 36 | ### API 37 | 38 | #### ChangeTitleOnLeave([options]) 39 | 40 | ##### options 41 | 42 | ###### title 43 | 44 | Type: `string` 45 | 46 | A string with the title to apply on the tab 47 | 48 | ###### timeout 49 | 50 | Type: `number` 51 | 52 | Timeout between the transistion of titles 53 | 54 | ###### onHidden 55 | 56 | Type: `function` 57 | 58 | Is called when the user leaves the tab. 59 | 60 | ###### onVisible 61 | 62 | Type: `function` 63 | 64 | Is called when the user goes back to the tab. 65 | -------------------------------------------------------------------------------- /change-title-onleave.js: -------------------------------------------------------------------------------- 1 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ChangeTitleOnLeave = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && arguments[0] !== undefined ? arguments[0] : {}; 53 | 54 | this.options = {}; 55 | this.title = document.title; 56 | 57 | if (!options.title || options.title === '') { 58 | throw Error('The `title` is required and must be a string.'); 59 | } 60 | 61 | this.options.title = options.title; 62 | this.options.timeout = typeof options.timeout === 'number' ? options.timeout : 0; 63 | this.options.onHidden = typeof options.onHidden === 'function' ? options.onHidden : null; 64 | this.options.onVisible = typeof options.onVisible === 'function' ? options.onVisible : null; 65 | } 66 | }, { 67 | key: 'listenVisibility', 68 | value: function listenVisibility() { 69 | var _this = this; 70 | 71 | window.addEventListener('visibilitychange', function () { 72 | return _this.handleVisibility(); 73 | }); 74 | } 75 | }, { 76 | key: 'handleVisibility', 77 | value: function handleVisibility() { 78 | var _this2 = this; 79 | 80 | var timeout = this.options.timeout; 81 | 82 | 83 | setTimeout(function () { 84 | return _this2.updateTitle(); 85 | }, timeout * 1000); 86 | } 87 | }, { 88 | key: 'updateTitle', 89 | value: function updateTitle() { 90 | var state = document.visibilityState; 91 | var _options = this.options, 92 | title = _options.title, 93 | onHidden = _options.onHidden, 94 | onVisible = _options.onVisible; 95 | 96 | 97 | if (state === 'hidden') { 98 | document.title = title; 99 | this.useCallback(onHidden); 100 | } 101 | 102 | if (state === 'visible') { 103 | document.title = this.title; 104 | this.useCallback(onVisible); 105 | } 106 | } 107 | }, { 108 | key: 'useCallback', 109 | value: function useCallback(callable) { 110 | if (!callable) return; 111 | 112 | callable(); 113 | } 114 | }]); 115 | 116 | return ChangeTitleOnLeave; 117 | }(); 118 | 119 | module.exports = ChangeTitleOnLeave; 120 | }); 121 | 122 | },{}]},{},[1])(1) 123 | }); -------------------------------------------------------------------------------- /change-title-onleave.min.js: -------------------------------------------------------------------------------- 1 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ChangeTitleOnLeave=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o0&&arguments[0]!==undefined?arguments[0]:{};this.title=document.title;if(!options.title||options.title===""){throw Error("The `title` is required and must be a string.")}this.options.title=options.title;this.options.timeout=typeof options.timeout==="number"?options.timeout:0;this.options.onHidden=typeof options.onHidden==="function"?options.onHidden:null;this.options.onVisible=typeof options.onVisible==="function"?options.onVisible:null}},{key:"listenVisibility",value:function listenVisibility(){var _this=this;window.addEventListener("visibilitychange",function(){return _this.handleVisibility()})}},{key:"handleVisibility",value:function handleVisibility(){var _this2=this;var timeout=this.options.timeout;setTimeout(function(){return _this2.updateTitle()},timeout*1e3)}},{key:"updateTitle",value:function updateTitle(){var state=document.visibilityState;var _options$title=this.options.title,title=_options$title.title,onHidden=_options$title.onHidden,onVisible=_options$title.onVisible;if(state==="hidden"){document.title=title}if(state==="visible"){document.title=this.title}}}]);return ChangeTitleOnLeave}();module.exports=ChangeTitleOnLeave})},{}]},{},[1])(1)}); -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | class ChangeTitleOnLeave { 2 | constructor(options) { 3 | this.resolveAttrs(options); 4 | this.listenVisibility(); 5 | } 6 | 7 | resolveAttrs(options = {}) { 8 | this.title = document.title; 9 | this.options = {}; 10 | 11 | if (! options.title || options.title === '') { 12 | throw Error('The `title` is required and must be a non-empty string.'); 13 | } 14 | 15 | this.options.title = options.title; 16 | this.options.timeout = typeof options.timeout === 'number' ? options.timeout : 0; 17 | this.options.onHidden = typeof options.onHidden === 'function' ? options.onHidden : null; 18 | this.options.onVisible = typeof options.onVisible === 'function' ? options.onVisible : null; 19 | } 20 | 21 | listenVisibility() { 22 | window.addEventListener('visibilitychange', () => this.handleVisibility()); 23 | } 24 | 25 | handleVisibility() { 26 | const {timeout} = this.options; 27 | 28 | setTimeout(() => this.updateTitle(), timeout * 1000); 29 | } 30 | 31 | updateTitle() { 32 | const state = document.visibilityState; 33 | const {title, onHidden, onVisible} = this.options; 34 | 35 | if (state === 'hidden') { 36 | document.title = title; 37 | this.useCallback(onHidden); 38 | } 39 | 40 | if (state === 'visible') { 41 | document.title = this.title; 42 | this.useCallback(onVisible); 43 | } 44 | } 45 | 46 | useCallback(callable) { 47 | if (typeof callable !== 'function') return; 48 | 49 | callable(); 50 | } 51 | } 52 | 53 | module.exports = ChangeTitleOnLeave; 54 | 55 | -------------------------------------------------------------------------------- /media/example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alisonmonteiro/change-title-onleave/f8c08c2fe9ad40dd11234b93fab834a78c28b876/media/example.gif -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "change-title-onleave", 3 | "version": "0.0.5", 4 | "description": "Change the tab title by change its visibility", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "serve", 8 | "build": "browserify index.js -s ChangeTitleOnLeave -t [babelify] -o change-title-onleave.js", 9 | "build-min": "uglifyjs change-title-onleave.js -o change-title-onleave.min.js", 10 | "deploy": "ns -c 'list . -s'", 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/alisonmonteiro/change-title-onleave.git" 16 | }, 17 | "author": { 18 | "name": "Alison", 19 | "email": "alisonmonteiro.10@gmail.com", 20 | "url": "alisonmonteiro.com.br" 21 | }, 22 | "keywords": [ 23 | "window", 24 | "events", 25 | "js", 26 | "tabs", 27 | "onchange", 28 | "onblur" 29 | ], 30 | "license": "MIT", 31 | "bugs": { 32 | "url": "https://github.com/alisonmonteiro/change-title-onleave/issues" 33 | }, 34 | "homepage": "https://github.com/alisonmonteiro/change-title-onleave#readme", 35 | "devDependencies": { 36 | "babel-cli": "^6.24.1", 37 | "babel-core": "^6.24.1", 38 | "babel-plugin-transform-es2015-modules-umd": "^6.24.1", 39 | "babel-preset-es2015": "^6.24.1", 40 | "babelify": "^7.3.0", 41 | "browserify": "^14.4.0", 42 | "uglify-js": "^3.0.16" 43 | } 44 | } 45 | --------------------------------------------------------------------------------