1/*********************************************** 2 needPopup 3 - Version 1.0.0 4 - Copyright 2015 Dzmitry Vasileuski 5 - Licensed under MIT (http://opensource.org/licenses/MIT) 6***********************************************/ 7 8// popup object 9var needPopup = (function() { 10 11 // namespace 12 var popup = {}; 13 // cached nodes 14 popup.html = document.documentElement, 15 popup.body = document.body, 16 popup.window = window, 17 // state variables 18 popup.target = 0, 19 // window scroll top 20 popup.scrollTopVal = 0, 21 // window scroll height 22 popup.scrollHeight = popup.body.scrollHeight > popup.html.scrollHeight ? popup.body.scrollHeight : popup.html.scrollHeight, 23 // html class when popup is opened 24 popup.openHtmlClass = popup.scrollHeight > popup.window.innerHeight ? 'needpopup-opened needpopup-scrolled' : 'needpopup-opened'; 25 26 // global methods and properties 27 return { 28 29 /* Initialization of popup 30 ***********************************************/ 31 init : function() { 32 33 // set default config 34 popup.options = needPopup.config.default; 35 36 // bind popup show to data-popupshow nodes 37 $(popup.body).on('click','[data-needpopup-show]', function(event) { 38 event.preventDefault(); 39 needPopup.show($(this).data('needpopupShow'),$(this)); 40 }) 41 42 // bind popup hide to removers 43 $(popup.body).on('click','.needpopup_wrapper .remove, .needpopup_remover', function(event) { 44 event.preventDefault(); 45 needPopup.hide(); 46 }) 47 48 // bind popup hide if clicked outside 49 $(popup.body).on('click','.needpopup_wrapper', function(event) { 50 console.log($(event.target).is('.needpopup_wrapper')); 51 if (!$(event.target).is('.needpopup_wrapper')) return; 52 53 event.preventDefault(); 54 if (!popup.options.closeOnOutside) return; 55 56 // check if clicked outside of popup window 57 if ($(event.target).closest('.needpopup').length || $(event.target).is('.needpopup, .remove, .needpopup_remover')) return; 58 59 needPopup.hide(); 60 }) 61 62 // hide popup on Esc 63 $(document).keydown(function(event){ 64 if (event.which == 27) { 65 needPopup.hide(); 66 } 67 }) 68 69 // corrections on window resize 70 popup.resizeTimeout = 0; 71 popup.resizeAllowed = true; 72 $(popup.window).on('resize',function() { 73 // throttling 74 clearTimeout(popup.resizeTimeout); 75 if (popup.resizeAllowed) { 76 popup.resizeAllowed = false; 77 78 // centrify popup 79 needPopup.centrify(); 80 // recalculate window scroll height 81 popup.scrollHeight = popup.body.scrollHeight > popup.html.scrollHeight ? popup.body.scrollHeight : popup.html.scrollHeight, 82 // change open htmml class if needed 83 popup.openHtmlClass = popup.scrollHeight > popup.window.innerHeight ? 'needpopup-opened needpopup-scrolled' : 'needpopup-opened'; 84 } 85 popup.resizeTimeout = setTimeout(function() { 86 popup.resizeAllowed = true; 87 }, 100); 88 }) 89 90 // create popup wrapper 91 popup.wrapper = document.createElement('div'); 92 popup.wrapper.className = 'needpopup_wrapper'; 93 popup.body.appendChild(popup.wrapper); 94 popup.wrapper = $(popup.wrapper); 95 }, 96 97 /* Show popup 98 ***********************************************/ 99 show : function(_target, _trigger) { 100 101 // save popup trigger if it exists 102 if (!_trigger) 103 popup.trigger = 0; 104 else 105 popup.trigger = _trigger; 106 107 // hide already opened popup 108 if (popup.target) 109 needPopup.hide(true); 110 else { 111 // recalculate window scroll top 112 popup.scrollTopVal = popup.window.pageYOffset; 113 114 // block page scroll 115 $(popup.body).css({'top': -popup.scrollTopVal}); 116 $(popup.html).addClass(popup.openHtmlClass); 117 } 118 119 // set target popup 120 popup.target = $(_target); 121 122 // reset options if defined 123 popup.options = needPopup.config['default']; 124 if (!!popup.target.data('needpopupOptions')) 125 $.extend( popup.options, needPopup.config[popup.target.data('needpopupOptions')] ); 126 127 128 // cache popup width 129 popup.minWidth = popup.target.outerWidth(); 130 131 // create layout 132 popup.wrapper.append(popup.target); 133 if (popup.options.removerPlace == 'outside') 134 popup.wrapper.after('<a href="#" class="needpopup_remover"></a>'); 135 else if (popup.options.removerPlace == 'inside') 136 popup.target.append('<a href="#" class="needpopup_remover"></a>'); 137 138 // on before show callback 139 popup.options.onBeforeShow.call(popup,popup.target); 140 141 // display popup 142 popup.target.show(); 143 // centrify popup 144 needPopup.centrify(); 145 // add opened class to popup (timeout for transitions) 146 setTimeout(function(){ 147 popup.target.addClass('opened'); 148 149 // on show callback 150 popup.options.onShow.call(popup,popup.target); 151 },10); 152 }, 153 154 /* Hide popup 155 ***********************************************/ 156 hide : function(_partial) { 157 158 // hide popup 159 popup.target.hide().removeClass('opened'); 160 // delete remover 161 $('.needpopup_remover').remove(); 162 163 // full hiding 164 if (!_partial) { 165 166 // unblock page scroll 167 $(popup.html).removeClass(popup.openHtmlClass).removeClass('needpopup-overflow'); 168 $(popup.body).css({'top': 0}).scrollTop(popup.scrollTopVal); 169 $(popup.html).scrollTop(popup.scrollTopVal); 170 } 171 172 // on hide callback 173 popup.options.onHide.call(popup,popup.target); 174 175 // unset property 176 popup.target = 0; 177 }, 178 179 /* Centrify popup and set responsive classes 180 ***********************************************/ 181 centrify: function() { 182 if (popup.target) { 183 // vertical centrification 184 if (popup.target.outerHeight(true) > popup.window.innerHeight) 185 popup.target.addClass('stacked'); 186 else 187 popup.target.removeClass('stacked').css({'margin-top':-popup.target.outerHeight(true)/2, 'top':'50%'}); 188 189 // detect width overflow 190 popup.minWidth = $(popup.html).hasClass('needpopup-overflow') ? popup.minWidth : popup.target.outerWidth(); 191 if (popup.minWidth + 30 >= popup.window.innerWidth) { 192 $(popup.html).addClass('needpopup-overflow'); 193 } else { 194 $(popup.html).removeClass('needpopup-overflow'); 195 } 196 } 197 }, 198 199 /* Configuration object which contains all options sets 200 ***********************************************/ 201 'config': { 202 'default' : { 203 // 'outside' to place in wrapper and 'inside' to place in popup 204 'removerPlace': 'inside', 205 // close on click outside popup 206 'closeOnOutside': true, 207 // on show callback 208 onShow: function() {}, 209 // on before show callback 210 onBeforeShow: function() {}, 211 // on hide callback 212 onHide: function() {} 213 } 214 } 215 216 } 217 218})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.