├── LICENSE ├── README.md ├── demo ├── example.gif └── index.html ├── overlay.css ├── overlay.js ├── overlay.min.css └── overlay.min.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Matthias Thalmann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # overlayJS 2 | 3 | OverlayJS is a simple JavaScript library, to display overlays. 4 | 5 | **Demo:** https://m-thalmann.github.io/overlayjs/demo/ 6 | 7 | ## Navigation 8 | - [Installation](#installation) 9 | - [Usage](#usage) 10 | - [Documentation](#documentation) 11 | - [Overlay](#overlay) 12 | - [OverlayManager](#overlaymanager) 13 | - [Events](#events) 14 | - [Options](#options) 15 | - [Example](#example) 16 | 17 | ## Installation 18 | 1. Download the .zip-File and put it in your project-folder. 19 | 20 | 2. Add this script-tag to the head of the file 21 | ```html 22 | 23 | ``` 24 | 25 | 3. Add this link-tag to the head of the file, to include the styles 26 | ```html 27 | 28 | ``` 29 | 30 | 4. Start using the library! 31 | 32 | ## Usage 33 | ### Create new Overlay 34 | ```javascript 35 | var overlay = new Overlay(); 36 | ``` 37 | 38 | ### Change the text 39 | ```javascript 40 | overlay.content.innerHTML = "This is a overlay"; 41 | ``` 42 | 43 | ### Close it 44 | ```javascript 45 | overlay.close(); 46 | ``` 47 | 48 | ### Open it again 49 | ```javascript 50 | overlay.open(); 51 | ``` 52 | 53 | ## Documentation 54 | ### Overlay 55 | Its the main object to display a overlay. 56 | #### Instanciating 57 | ```javascript 58 | new Overlay(options); 59 | ``` 60 | - **options** (object): A object with options for the overlay (see [below](#options)) **(optional)** 61 | 62 | After instanciating the overlay is shown (if not defined otherwise) 63 | 64 | #### Methods 65 | ```javascript 66 | overlay.open(); // Opens the overlay, if its not allready open 67 | overlay.close(force); // Closes the overlay, if its not allready closed; 68 | // if the force parameter is set, it will be closed for sure (boolean) 69 | overlay.isOpened(); // Returns true, if the overlay is open, otherwise false 70 | 71 | overlay.on(event, callback); // Sets the eventlistener of the event, if the callback is specified; 72 | // if only the event is set, it returns the callback-function; if that is not 73 | // set, it returns a empty function (string, function) 74 | overlay.removeOn(event); // Removes the eventlistener for the event, if set (string) 75 | 76 | overlay.reset(); // Resets the content of the overlay 77 | ``` 78 | 79 | #### Variables 80 | ```javascript 81 | overlay.content // A div, that contains the content of the overlay (edit this!) 82 | 83 | Overlay.CLOSING_DURATION // Sets, when the overlay is removed from the DOM after closing (ms) 84 | ``` 85 | 86 | ### OverlayManager 87 | Its used to manage overlays, so that only one at a time is displayed. Can't be instanciated. 88 | #### Methods 89 | ```javascript 90 | OverlayManager.create(options); // Creates a new overlay, adds it to the manager and returns it; 91 | // the returned overlay is not a instance of Overlay but 92 | // of a anonymous type (object) 93 | OverlayManager.remove(overlay); // Remove the overlay completely (can't open it again) (anonymous overlay-type) 94 | ``` 95 | The recieved overlay from the OverlayManager can be used normally. 96 | 97 | ### Events 98 | It is possible to attach a event to a overlay: overlay.on(event, callback); 99 | 100 | | Event | Definition | 101 | |---------|------------------------------------------------------------------------------------------------------| 102 | | opening | Is triggered, before the overlay is opened; if the callback returns false, the overlay is not opened | 103 | | open | Is triggered, after the overlay is opened | 104 | | closing | Is triggered, before the overlay is closed; if the callback returns false, the overlay is not closed | 105 | | close | Is triggered, after the overlay is closed | 106 | 107 | ### Options 108 | 109 | | Option | Values | Definition | 110 | |----------|------------|-------------------------------------------------------| 111 | | closable | true/false | Defines, if the overlay is closable by the user | 112 | | opened | true/false | Defines, if the overlay is opened on creation, or not | 113 | 114 | ## Example 115 | ### Code 116 | ```javascript 117 | var overlay = new Overlay(); 118 | 119 | var btn_close = document.createElement("button"); 120 | btn_close.innerHTML = "Close"; 121 | btn_close.onclick = overlay.close; 122 | 123 | overlay.content.appendChild(btn_close); 124 | overlay.content.style.textAlign = "center"; 125 | ``` 126 | 127 | ### Output 128 | 129 | ![overlayJs example](demo/example.gif) 130 | -------------------------------------------------------------------------------- /demo/example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/m-thalmann/overlayjs/e251b6d21b89814f2022edee5247cf96791e7152/demo/example.gif -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | OverlayJS Test 7 | 8 | 9 | 10 | 11 | 12 |

OverlayJS Test

13 | 14 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /overlay.css: -------------------------------------------------------------------------------- 1 | .overlay{ 2 | position: fixed; 3 | top: 0; 4 | left: 0; 5 | right: 0; 6 | bottom: 0; 7 | animation: overlay_fadein 0.5s; 8 | background-color: rgba(0, 0, 0, 0.7); 9 | z-index: 100; 10 | } 11 | 12 | .overlay.overlay_closing{ 13 | animation: overlay_fadeout 0.5s; 14 | background-color: rgba(0, 0, 0, 0); 15 | } 16 | 17 | .overlay .overlay_content{ 18 | background-color: #fff; 19 | max-width: 100%; 20 | max-height: 100%; 21 | overflow: auto; 22 | min-width: 250px; 23 | min-height: 100px; 24 | position: absolute; 25 | top: 50%; 26 | left: 50%; 27 | transform: translate(-50%, -50%); 28 | box-shadow: 0px 0px 10px 0px #000; 29 | border-radius: 2px; 30 | animation: overlay_content_fadein 0.5s; 31 | opacity: 1; 32 | padding: 5px; 33 | } 34 | 35 | .overlay.overlay_closing .overlay_content{ 36 | animation: overlay_content_fadeout 0.5s; 37 | opacity: 0; 38 | box-shadow: none; 39 | } 40 | 41 | @keyframes overlay_fadein { 42 | 0%{ 43 | background-color: rgba(0, 0, 0, 0); 44 | } 45 | 46 | 100%{ 47 | background-color: rgba(0, 0, 0, 0.7); 48 | } 49 | } 50 | 51 | @keyframes overlay_content_fadein { 52 | 0%{ 53 | top: 45%; 54 | opacity: 0; 55 | } 56 | 57 | 100%{ 58 | top: 50%; 59 | opacity: 1; 60 | } 61 | } 62 | 63 | @keyframes overlay_fadeout { 64 | 0%{ 65 | background-color: rgba(0, 0, 0, 0.7); 66 | } 67 | 68 | 100%{ 69 | background-color: rgba(0, 0, 0, 0); 70 | } 71 | } 72 | 73 | @keyframes overlay_content_fadeout { 74 | 0%{ 75 | top: 50%; 76 | opacity: 1; 77 | } 78 | 79 | 100%{ 80 | top: 45%; 81 | opacity: 0; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /overlay.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple JavaScript library, to display overlays 3 | * 4 | * @author Matthias Thalmann (https://github.com/m-thalmann/) 5 | * @license MIT 6 | */ 7 | 8 | var Overlay = (function(){ 9 | function Overlay(options){ 10 | var overlay = document.createElement("div"); 11 | overlay.className = "overlay"; 12 | var open = false; 13 | var events = []; 14 | var self = this; 15 | 16 | this.content = null; 17 | 18 | this.open = function(){ 19 | if(open || self.on("opening")() === false){ 20 | return false; 21 | } 22 | 23 | open = true; 24 | overlay.appendChild(this.content); 25 | document.body.appendChild(overlay); 26 | document.body.style.overflow = 'hidden'; 27 | self.on("open")(); 28 | }; 29 | 30 | this.close = function(force){ 31 | if(!open || (!force && self.on("closing")() === false)){ 32 | return false; 33 | } 34 | 35 | document.body.style.overflow = null; 36 | 37 | overlay.classList.add("overlay_closing"); 38 | setTimeout(function(){ 39 | overlay.parentNode.removeChild(overlay); 40 | overlay.classList.remove("overlay_closing"); 41 | open = false; 42 | self.on("close")(); 43 | }, Overlay.CLOSING_DURATION); 44 | }; 45 | 46 | this.reset = function(){ 47 | if(self.content){ 48 | self.content.remove(); 49 | } 50 | self.content = document.createElement("div"); 51 | self.content.className = "overlay_content"; 52 | }; 53 | 54 | this.on = function(ev, callback){ 55 | if(typeof callback !== "function"){ 56 | if(typeof events[ev] === "function"){ 57 | return events[ev]; 58 | }else{ 59 | return function(){}; 60 | } 61 | }else{ 62 | events[ev] = callback; 63 | } 64 | }; 65 | 66 | this.removeOn = function(ev){ 67 | delete events[ev]; 68 | }; 69 | 70 | this.isOpened = function(){ 71 | return open; 72 | }; 73 | 74 | //Init 75 | (function(){ 76 | if(typeof options !== "object"){ 77 | options = {}; 78 | } 79 | 80 | self.reset(); 81 | 82 | if(getProperty(options, "closable", true)){ 83 | overlay.addEventListener("click", function(e){ 84 | if(!isDescendant(self.content, e.target)){ 85 | self.close(); 86 | } 87 | }); 88 | } 89 | 90 | if(getProperty(options, "opened", true)){ 91 | self.open(); 92 | } 93 | }()); 94 | } 95 | 96 | Overlay.CLOSING_DURATION = 500; //ms 97 | 98 | function getProperty(options, opt, def){ 99 | if(typeof options[opt] !== "undefined"){ 100 | return options[opt]; 101 | }else{ 102 | return def; 103 | } 104 | } 105 | 106 | function isDescendant(parent, node){ 107 | while(node != parent && node != document.body){ 108 | node = node.parentElement; 109 | } 110 | 111 | return node == parent; 112 | } 113 | 114 | return Overlay; 115 | }()); 116 | 117 | var OverlayManager = (function(){ 118 | var overlays = []; 119 | var opened = -1; 120 | 121 | const _manager = { 122 | create: function(options){ 123 | if(typeof options === "undefined"){ 124 | options = {opened: true}; 125 | } 126 | var to_open = false; 127 | 128 | if(typeof options.opened !== "undefined"){ 129 | to_open = options.opened; 130 | } 131 | 132 | options.opened = false; 133 | 134 | var pos = overlays.push(new Overlay(options)) - 1; 135 | 136 | var nov = new ManagedOverlay(pos); 137 | if(to_open){ 138 | nov.open(); 139 | } 140 | 141 | return nov; 142 | }, 143 | 144 | remove: function(moverlay){ 145 | var pos = moverlay.getPos(); 146 | overlays[pos].close(); 147 | delete overlays[pos]; 148 | } 149 | }; 150 | 151 | function ManagedOverlay(pos){ 152 | this.content = document.createElement("div"); 153 | this.content.className = "overlay_content"; 154 | overlays[pos].content = this.content; 155 | 156 | this.open = function(){ 157 | return open(pos); 158 | }; 159 | 160 | this.close = function(force){ 161 | return close(pos, force); 162 | }; 163 | 164 | this.on = function(ev, callback){ 165 | return overlays[pos].on(ev, callback); 166 | }; 167 | 168 | this.removeOn = function(ev){ 169 | return overlays[pos].removeOn(ev); 170 | }; 171 | 172 | this.isOpened = function(){ 173 | return overlays[pos].isOpened(); 174 | }; 175 | 176 | this.getPos = function(){ 177 | return pos; 178 | }; 179 | } 180 | 181 | function open(pos){ 182 | if(overlays[pos] instanceof Overlay){ 183 | if(opened != -1){ 184 | if(overlays[opened].close() !== false){ 185 | opened = pos; 186 | overlays[pos].open(); 187 | }else{ 188 | console.warn("The currently open overlay does not want to be closed"); 189 | } 190 | }else{ 191 | opened = pos; 192 | overlays[pos].open(); 193 | } 194 | }else{ 195 | throw new Error("This overlay has been deleted"); 196 | } 197 | } 198 | 199 | function close(pos, force){ 200 | if(overlays[pos] instanceof Overlay){ 201 | if(opened == pos){ 202 | if(overlays[pos].close(force) !== false){ 203 | opened = -1; 204 | } 205 | } 206 | }else{ 207 | throw new Error("This overlay has been deleted"); 208 | } 209 | } 210 | 211 | return _manager; 212 | }()); 213 | -------------------------------------------------------------------------------- /overlay.min.css: -------------------------------------------------------------------------------- 1 | .overlay{position:fixed;top:0;left:0;right:0;bottom:0;animation:overlay_fadein .5s;background-color:rgba(0,0,0,.7);z-index:100}.overlay.overlay_closing{animation:overlay_fadeout .5s;background-color:rgba(0,0,0,0)}.overlay .overlay_content{background-color:#fff;max-width:100%;max-height:100%;overflow:auto;min-width:250px;min-height:100px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);box-shadow:0 0 10px 0 #000;border-radius:2px;animation:overlay_content_fadein .5s;opacity:1;padding:5px}.overlay.overlay_closing .overlay_content{animation:overlay_content_fadeout .5s;opacity:0;box-shadow:none}@keyframes overlay_fadein{0%{background-color:rgba(0,0,0,0)}100%{background-color:rgba(0,0,0,.7)}}@keyframes overlay_content_fadein{0%{top:45%;opacity:0}100%{top:50%;opacity:1}}@keyframes overlay_fadeout{0%{background-color:rgba(0,0,0,.7)}100%{background-color:rgba(0,0,0,0)}}@keyframes overlay_content_fadeout{0%{top:50%;opacity:1}100%{top:45%;opacity:0}} 2 | -------------------------------------------------------------------------------- /overlay.min.js: -------------------------------------------------------------------------------- 1 | var Overlay=function(){function e(o){var r=document.createElement("div");r.className="overlay";var c=!1,i=[],s=this;this.content=null,this.open=function(){return c||s.on("opening")()===!1?!1:(c=!0,r.appendChild(this.content),document.body.appendChild(r),document.body.style.overflow="hidden",void s.on("open")())},this.close=function(n){return!c||!n&&s.on("closing")()===!1?!1:(document.body.style.overflow=null,r.classList.add("overlay_closing"),void setTimeout(function(){r.parentNode.removeChild(r),r.classList.remove("overlay_closing"),c=!1,s.on("close")()},e.CLOSING_DURATION))},this.reset=function(){s.content&&s.content.remove(),s.content=document.createElement("div"),s.content.className="overlay_content"},this.on=function(e,n){return"function"!=typeof n?"function"==typeof i[e]?i[e]:function(){}:void(i[e]=n)},this.removeOn=function(e){delete i[e]},this.isOpened=function(){return c},function(){"object"!=typeof o&&(o={}),s.reset(),n(o,"closable",!0)&&r.addEventListener("click",function(e){t(s.content,e.target)||s.close()}),n(o,"opened",!0)&&s.open()}()}function n(e,n,t){return"undefined"!=typeof e[n]?e[n]:t}function t(e,n){for(;n!=e&&n!=document.body;)n=n.parentElement;return n==e}return e.CLOSING_DURATION=500,e}(),OverlayManager=function(){function e(e){this.content=document.createElement("div"),this.content.className="overlay_content",o[e].content=this.content,this.open=function(){return n(e)},this.close=function(n){return t(e,n)},this.on=function(n,t){return o[e].on(n,t)},this.removeOn=function(n){return o[e].removeOn(n)},this.isOpened=function(){return o[e].isOpened()},this.getPos=function(){return e}}function n(e){if(!(o[e]instanceof Overlay))throw new Error("This overlay has been deleted");-1!=r?o[r].close()!==!1?(r=e,o[e].open()):console.warn("The currently open overlay does not want to be closed"):(r=e,o[e].open())}function t(e,n){if(!(o[e]instanceof Overlay))throw new Error("This overlay has been deleted");r==e&&o[e].close(n)!==!1&&(r=-1)}var o=[],r=-1;const c={create:function(n){"undefined"==typeof n&&(n={opened:!0});var t=!1;"undefined"!=typeof n.opened&&(t=n.opened),n.opened=!1;var r=o.push(new Overlay(n))-1,c=new e(r);return t&&c.open(),c},remove:function(e){var n=e.getPos();o[n].close(),delete o[n]}};return c}(); --------------------------------------------------------------------------------