1/* 2 * backgroundSize: A jQuery cssHook adding support for "cover" and "contain" to IE6,7,8 3 * 4 * Requirements: 5 * - jQuery 1.7.0+ 6 * 7 * Limitations: 8 * - doesn't work with multiple backgrounds (use the :after trick) 9 * - doesn't work with the "4 values syntax" of background-position 10 * - doesn't work with lengths in background-position (only percentages and keywords) 11 * - doesn't work with "background-repeat: repeat;" 12 * - doesn't work with non-default values of background-clip/origin/attachment/scroll 13 * - you should still test your website in IE! 14 * 15 * latest version and complete README available on Github: 16 * https://github.com/louisremi/jquery.backgroundSize.js 17 * 18 * Copyright 2012 @louis_remi 19 * Licensed under the MIT license. 20 * 21 * This saved you an hour of work? 22 * Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON 23 * 24 */ 25(function($,window,document,Math,undefined) { 26 27var div = $( "<div>" )[0], 28 rsrc = /url\(["']?(.*?)["']?\)/, 29 watched = [], 30 positions = { 31 top: 0, 32 left: 0, 33 bottom: 1, 34 right: 1, 35 center: .5 36 }; 37 38// feature detection 39if ( "backgroundSize" in div.style && !$.debugBGS ) { return; } 40 41$.cssHooks.backgroundSize = { 42 set: function( elem, value ) { 43 var firstTime = !$.data( elem, "bgsImg" ), 44 pos, 45 $wrapper, $img; 46 47 $.data( elem, "bgsValue", value ); 48 49 if ( firstTime ) { 50 // add this element to the 'watched' list so that it's updated on resize 51 watched.push( elem ); 52 53 $.refreshBackgroundDimensions( elem, true ); 54 55 // create wrapper and img 56 $wrapper = $( "<div>" ).css({ 57 position: "absolute", 58 zIndex: -1, 59 top: 0, 60 right: 0, 61 left: 0, 62 bottom: 0, 63 overflow: "hidden" 64 }); 65 66 $img = $( "<img>" ).css({ 67 position: "absolute" 68 }).appendTo( $wrapper ), 69 70 $wrapper.prependTo( elem ); 71 72 $.data( elem, "bgsImg", $img[0] ); 73 74 pos = ( 75 // Firefox, Chrome (for debug) 76 $.css( elem, "backgroundPosition" ) || 77 // IE8 78 $.css( elem, "backgroundPositionX" ) + " " + $.css( elem, "backgroundPositionY" ) 79 ).split(" "); 80 81 // Only compatible with 1 or 2 percentage or keyword values, 82 // Not yet compatible with length values and 4 values. 83 $.data( elem, "bgsPos", [ 84 positions[ pos[0] ] || parseFloat( pos[0] ) / 100, 85 positions[ pos[1] ] || parseFloat( pos[1] ) / 100 86 ]); 87 88 // This is the part where we mess with the existing DOM 89 // to make sure that the background image is correctly zIndexed 90 $.css( elem, "zIndex" ) == "auto" && ( elem.style.zIndex = 0 ); 91 $.css( elem, "position" ) == "static" && ( elem.style.position = "relative" ); 92 93 $.refreshBackgroundImage( elem ); 94 95 } else { 96 $.refreshBackground( elem ); 97 } 98 }, 99 100 get: function( elem ) { 101 return $.data( elem, "bgsValue" ) || ""; 102 } 103}; 104 105// The background should refresh automatically when changing the background-image 106$.cssHooks.backgroundImage = { 107 set: function( elem, value ) { 108 // if the element has a backgroundSize, refresh its background 109 return $.data( elem, "bgsImg") ? 110 $.refreshBackgroundImage( elem, value ) : 111 // otherwise set the background-image normally 112 value; 113 } 114}; 115 116$.refreshBackgroundDimensions = function( elem, noBgRefresh ) { 117 var $elem = $(elem), 118 currDim = { 119 width: $elem.innerWidth(),
120 height: $elem.innerHeight() 121 }, 122 prevDim = $.data( elem, "bgsDim" ), 123 changed = !prevDim || 124 currDim.width != prevDim.width || 125 currDim.height != prevDim.height; 126 127 $.data( elem, "bgsDim", currDim ); 128 129 if ( changed && !noBgRefresh ) { 130 $.refreshBackground( elem ); 131 } 132}; 133 134$.refreshBackgroundImage = function( elem, value ) { 135 var img = $.data( elem, "bgsImg" ), 136 currSrc = ( rsrc.exec( value || $.css( elem, "backgroundImage" ) ) || [] )[1], 137 prevSrc = img && img.src, 138 changed = currSrc != prevSrc, 139 imgWidth, imgHeight; 140 141 if ( changed ) { 142 img.style.height = img.style.width = "auto"; 143 144 img.onload = function() { 145 var dim = { 146 width: img.width, 147 height: img.height 148 }; 149 150 // ignore onload on the proxy image 151 if ( dim.width == 1 && dim.height == 1 ) { return; } 152 153 $.data( elem, "bgsImgDim", dim ); 154 $.data( elem, "bgsConstrain", false ); 155 156 $.refreshBackground( elem ); 157 158 img.style.visibility = "visible"; 159 160 img.onload = null; 161 }; 162 163 img.style.visibility = "hidden"; 164 img.src = currSrc; 165 166 if ( img.readyState || img.complete ) { 167 img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; 168 img.src = currSrc; 169 } 170 171 elem.style.backgroundImage = "none"; 172 } 173}; 174 175$.refreshBackground = function( elem ) { 176 var value = $.data( elem, "bgsValue" ), 177 elemDim = $.data( elem, "bgsDim" ), 178 imgDim = $.data( elem, "bgsImgDim" ), 179 $img = $( $.data( elem, "bgsImg" ) ), 180 pos = $.data( elem, "bgsPos" ), 181 prevConstrain = $.data( elem, "bgsConstrain" ), 182 currConstrain, 183 elemRatio = elemDim.width / elemDim.height, 184 imgRatio = imgDim.width / imgDim.height, 185 delta; 186 187 if ( value == "contain" ) { 188 if ( imgRatio > elemRatio ) { 189 $.data( elem, "bgsConstrain", ( currConstrain = "width" ) ); 190 191 delta = Math.floor( ( elemDim.height - elemDim.width / imgRatio ) * pos[1] ); 192 193 $img.css({ 194 top: delta 195 }); 196 197 // when switchin from height to with constraint, 198 // make sure to release contraint on height and reset left 199 if ( currConstrain != prevConstrain ) { 200 $img.css({ 201 width: "100%", 202 height: "auto", 203 left: 0 204 }); 205 } 206 207 } else { 208 $.data( elem, "bgsConstrain", ( currConstrain = "height" ) ); 209 210 delta = Math.floor( ( elemDim.width - elemDim.height * imgRatio ) * pos[0] ); 211 212 $img.css({ 213 left: delta 214 }); 215 216 if ( currConstrain != prevConstrain ) { 217 $img.css({ 218 height: "100%", 219 width: "auto", 220 top: 0 221 }); 222 } 223 } 224 225 } else if ( value == "cover" ) { 226 if ( imgRatio > elemRatio ) { 227 $.data( elem, "bgsConstrain", ( currConstrain = "height" ) ); 228 229 delta = Math.floor( ( elemDim.height * imgRatio - elemDim.width ) * pos[0] ); 230 231 $img.css({ 232 left: -delta 233 }); 234 235 if ( currConstrain != prevConstrain ) { 236 $img.css({ 237 height:"100%", 238 width: "auto", 239 top: 0 240 }); 241 } 242 243 } else { 244 $.data( elem, "bgsConstrain", ( currConstrain = "width" ) ); 245 246 delta = Math.floor( ( elemDim.width / imgRatio - elemDim.height ) * pos[1] ); 247 248 $img.css({ 249 top: -delta 250 }); 251 252 if ( currConstrain != prevConstrain ) { 253 $img.css({ 254 width: "100%", 255 height: "auto", 256 left: 0 257 }); 258 } 259 } 260 } 261} 262 263// Built-in throttledresize 264var $event = $.event, 265 $special, 266 dummy = {_:0}, 267 frame = 0, 268 wasResized, animRunning; 269 270$special = $event.special.throttledresize = { 271 setup: function() { 272 $( this ).on( "resize", $special.handler ); 273 }, 274 teardown: function() { 275 $( this ).off( "resize", $special.handler ); 276 }, 277 handler: function( event, execAsap ) { 278 // Save the context 279 var context = this, 280 args = arguments; 281 282 wasResized = true; 283 284 if ( !animRunning ) { 285 $(dummy).animate(dummy, { duration: Infinity, step: function() { 286 frame++; 287 288 if ( frame > $special.threshold && wasResized || execAsap ) { 289 // set correct event type 290 event.type = "throttledresize"; 291 $event.dispatch.apply( context, args ); 292 wasResized = false; 293 frame = 0; 294 } 295 if ( frame > 9 ) { 296 $(dummy).stop(); 297 animRunning = false; 298 frame = 0; 299 } 300 }}); 301 animRunning = true; 302 } 303 }, 304 threshold: 1 305}; 306 307// All backgrounds should refresh automatically when the window is resized 308$(window).on("throttledresize", function() { 309 $(watched).each(function() {
310 $.refreshBackgroundDimensions( this ); 311 }); 312}); 313 314})(jQuery,window,document,Math);
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.