1/*! 2 * Nu Slidepop - nu_slidepop 3 * Copyright (C) 2013 Adam Tavares 4 * http://adamtavares.com 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25;(function($) { 26 27 function nu_slidepop( elem, options, id ) { 28 var self = this; 29 self.elem = elem; 30 self.id = id; 31 self.init( elem, options ); 32 } 33 34 nu_slidepop.prototype.init = function( elem, options ) { 35 var self = this; 36 37 //--------------- 38 // User options 39 //--------------- 40 self.options = $.extend({ 41 html: null, 42 easing: 'swing', 43 speed: 1, 44 close: 'X', 45 click_outside_hide: true, 46 }, options); 47 self.options['speed'] *= 1000; // Seconds to milliseconds 48 49 //----------------------------------- 50 // Shared instance method variables 51 //----------------------------------- 52 self.obj = { 53 lock: false, 54 focus_lock: false, 55 }; 56 57 self.create(); 58 } 59 60 nu_slidepop.prototype.noClickOutsideHide = function() { 61 var self = this; 62 self.options['click_outside_hide'] = false; 63 } 64 65 nu_slidepop.prototype.create = function() { 66 var self = this; 67 68 $( self.elem ).addClass( 'nu_slidepop' ); 69 70 $( self.elem ).css({ 71 'position': 'fixed', 72 'display': 'none', 73 'left': 0, 74 'margin': 0, 75 'z-index': 5000 76 }); 77 78 //---------------------------------------- 79 // Create a clear below the close button 80 //---------------------------------------- 81 if ( self.options['close'] != null ) { 82 var close = $(document.createElement('a')); 83 close.html( self.options['close'] ); 84 close.attr( 'href', '#' ); 85 close.addClass('close'); 86 87 //---------------------------------- 88 // Add the close button to the DOM 89 //---------------------------------- 90 $( self.elem ).prepend( close ); 91 92 close.click( function(e) { 93 self.hide(); 94 e.preventDefault(); 95 }); 96 } 97 98 //------------------------------------------------------------ 99 // Set height now rather than earlier to ensure 100 // jQuery returns and accurate height value. 101 //------------------------------------------------------------ 102 self.obj['height'] = $( self.elem ).outerHeight(); 103 $( self.elem ).css({ 104 'bottom': self.obj['height'] * -1 105 }) 106 } 107 108 nu_slidepop.prototype.hide = function() { 109 var self = this; 110 var bottom = parseInt( $( self.elem ).css( 'bottom' ).replace( 'px', '' ) ); 111 if ( bottom == 0 && self.obj['lock'] != true ) { 112 113 self.obj['lock'] = true; // lock down. 114 115 $( self.elem ).animate( 116 {'bottom': '-='+self.obj['height']+'px' }, 117 self.options['speed'], 118 self.options['easing'], 119 function(){ 120 self.obj['lock'] = false; 121 //------------------------------------------------------------ 122 // iOS safari is slow on the redraw resulting in floating 123 // pop-ups that quickly disappear, so hide after animation. 124 //------------------------------------------------------------ 125 $( self.elem ).css({'display':'none'}); 126 } 127 ); 128 } 129 } 130 131 nu_slidepop.prototype.mobileFix = function() { 132 var self = this; 133 134 //------------------------------------------------------------ 135 // If input field gets focus stick slide in place so 136 // mobile device keyboards don't push out of window. 137 //------------------------------------------------------------ 138 $( 'input', self.elem ).focus( function(e){ 139 $( self.elem ).css({ 140 'position': 'absolute', 141 'top': $( self.elem ).position().top, 142 }); 143 self.obj['focus_lock'] = true; 144 }); 145 $( 'input', self.elem ).blur( function(e){ 146 $( self.elem ).css({ 147 'position': 'fixed', 148 'top': 'auto', 149 }); 150 self.obj['focus_lock'] = false;
151 }); 152 153 } 154 155 nu_slidepop.prototype.clickOutsideInit = function() { 156 var self = this; 157 $( window ).click( function(e){ 158 159 //------------------------------------------------------------ 160 // Form submission with an Enter button will trigger a 161 // window click event! But click coordinates will be zero. 162 // checking that e.pageY is greater than zero allows me to 163 // filter out false positives. 164 //------------------------------------------------------------ 165 if ( e.pageY > 0 && self.options['click_outside_hide'] == true && self.obj['focus_lock'] == false ) { 166 var clickY = e.pageY - $( window ).scrollTop(); 167 var hideZone = $( window ).height() - $( self.elem ).height(); 168 if ( clickY < hideZone || e.pageX > $( self.elem ).width() ) { 169 self.hide(); 170 } 171 } 172 }); 173 } 174 175 nu_slidepop.prototype.isMobile = function() { 176 var ua = navigator.userAgent; 177 if ( ua.match( /Android/i ) ) { 178 return 'android'; 179 } 180 else if ( ua.match( /BlackBerry/i ) ) { 181 return 'blackberry'; 182 } 183 else if ( ua.match( /iPhone|iPad|iPod/i ) ) { 184 return 'ios'; 185 } 186 else if ( ua.match( /Opera Mini/i ) ) { 187 return 'opera-mini'; 188 } 189 else if ( ua.match( /IEMobile/i ) ) { 190 return 'iemobile'; 191 } 192 else { 193 return false; 194 } 195 } 196 197 nu_slidepop.prototype.show = function() { 198 var self = this; 199 var bottom = parseInt( $( self.elem ).css( 'bottom' ).replace( 'px', '' ) ); 200 //--------------------- 201 // Show that pop-up 202 //--------------------- 203 if ( bottom < 0 && self.obj['lock'] != true ) { 204 205 self.obj['lock'] = true; // lock down. 206 //------------------------------------------------------------ 207 // iOS safari is slow on the redraw resulting in floating 208 // pop-ups that quickly disappear 209 //------------------------------------------------------------ 210 $( self.elem ).css({'display':'block'}); 211 212 $( self.elem ).animate( 213 {'bottom': '+='+self.obj['height']+'px' }, 214 self.options['speed'], 215 self.options['easing'], 216 217 //------------------------------------------------ 218 // If click outside perimeter of pop-up close 219 //------------------------------------------------ 220 function(){ 221 self.obj['lock'] = false; 222 223 //------------------------------------------------------------ 224 // Mobile fix. Prevents pop-up from jumping out of view 225 // when text field has focus. 226 //------------------------------------------------------------ 227 var mobile = self.isMobile(); 228 if ( mobile != false ) { 229 self.mobileFix(); 230 } 231 232 if ( self.options['click_outside_hide'] == true ) { 233 self.clickOutsideInit(); 234 } 235 } 236 ); 237 } 238 } 239 240 //---------------- 241 // Extend JQuery 242 //---------------- 243 jQuery(document).ready( function($) { 244 jQuery.fn.nu_slidepop = function( options ) { 245 var id = jQuery(this).selector; 246 return this.each( function() { 247 jQuery.data( this, id, new nu_slidepop( this, options, id ) ); 248 }); 249 }; 250 }) 251})(jQuery);
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.