|
1 | 1 | /*! matchMedia() polyfill addListener/removeListener extension. Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license */
|
2 | 2 | (function(){
|
3 |
| - // monkeypatch unsupported addListener/removeListener with polling |
4 |
| - if( !window.matchMedia( "all" ).addListener ){ |
5 |
| - var oldMM = window.matchMedia; |
6 |
| - |
7 |
| - window.matchMedia = function( q ){ |
8 |
| - var ret = oldMM( q ), |
9 |
| - listeners = [], |
10 |
| - last = ret.matches, |
11 |
| - timer, |
12 |
| - check = function(){ |
13 |
| - var list = oldMM( q ), |
14 |
| - unmatchToMatch = list.matches && !last, |
15 |
| - matchToUnmatch = !list.matches && last; |
16 |
| - |
17 |
| - //fire callbacks only if transitioning to or from matched state |
18 |
| - if( unmatchToMatch || matchToUnmatch ){ |
19 |
| - for( var i =0, il = listeners.length; i< il; i++ ){ |
20 |
| - listeners[ i ].call( ret, list ); |
21 |
| - } |
22 |
| - } |
23 |
| - last = list.matches; |
24 |
| - }; |
25 |
| - |
26 |
| - ret.addListener = function( cb ){ |
27 |
| - listeners.push( cb ); |
28 |
| - if( !timer ){ |
29 |
| - timer = setInterval( check, 1000 ); |
30 |
| - } |
31 |
| - }; |
32 |
| - |
33 |
| - ret.removeListener = function( cb ){ |
34 |
| - for( var i =0, il = listeners.length; i< il; i++ ){ |
35 |
| - if( listeners[ i ] === cb ){ |
36 |
| - listeners.splice( i, 1 ); |
37 |
| - } |
38 |
| - } |
39 |
| - if( !listeners.length && timer ){ |
40 |
| - clearInterval( timer ); |
41 |
| - } |
42 |
| - }; |
43 |
| - |
44 |
| - return ret; |
45 |
| - }; |
46 |
| - } |
| 3 | + // Bail out for browsers that have addListener support |
| 4 | + if (window.matchMedia && window.matchMedia('all').addListener) { |
| 5 | + return false; |
| 6 | + } |
| 7 | + |
| 8 | + var localMatchMedia = window.matchMedia, |
| 9 | + hasMediaQueries = localMatchMedia('only all').matches, |
| 10 | + isListening = false, |
| 11 | + timeoutID = 0, // setTimeout for debouncing 'handleChange' |
| 12 | + queries = [], // Contains each 'mql' and associated 'listeners' if 'addListener' is used |
| 13 | + handleChange = function(evt) { |
| 14 | + // Debounce |
| 15 | + clearTimeout(timeoutID); |
| 16 | + |
| 17 | + timeoutID = setTimeout(function() { |
| 18 | + for (var i = 0, il = queries.length; i < il; i++) { |
| 19 | + var mql = queries[i].mql, |
| 20 | + listeners = queries[i].listeners || [], |
| 21 | + matches = localMatchMedia(mql.media).matches; |
| 22 | + |
| 23 | + // Update mql.matches value and call listeners |
| 24 | + // Fire listeners only if transitioning to or from matched state |
| 25 | + if (matches !== mql.matches) { |
| 26 | + mql.matches = matches; |
| 27 | + |
| 28 | + for (var j = 0, jl = listeners.length; j < jl; j++) { |
| 29 | + listeners[j].call(window, mql); |
| 30 | + } |
| 31 | + } |
| 32 | + } |
| 33 | + }, 30); |
| 34 | + }; |
| 35 | + |
| 36 | + window.matchMedia = function(media) { |
| 37 | + var mql = localMatchMedia(media), |
| 38 | + listeners = [], |
| 39 | + index = 0; |
| 40 | + |
| 41 | + mql.addListener = function(listener) { |
| 42 | + // Changes would not occur to css media type so return now (Affects IE <= 8) |
| 43 | + if (!hasMediaQueries) { |
| 44 | + return; |
| 45 | + } |
| 46 | + |
| 47 | + // Set up 'resize' listener for browsers that support CSS3 media queries (Not for IE <= 8) |
| 48 | + // There should only ever be 1 resize listener running for performance |
| 49 | + if (!isListening) { |
| 50 | + isListening = true; |
| 51 | + window.addEventListener('resize', handleChange, true); |
| 52 | + } |
| 53 | + |
| 54 | + // Push object only if it has not been pushed already |
| 55 | + if (index === 0) { |
| 56 | + index = queries.push({ |
| 57 | + mql : mql, |
| 58 | + listeners : listeners |
| 59 | + }); |
| 60 | + } |
| 61 | + |
| 62 | + listeners.push(listener); |
| 63 | + }; |
| 64 | + |
| 65 | + mql.removeListener = function(listener) { |
| 66 | + for (var i = 0, il = listeners.length; i < il; i++){ |
| 67 | + if (listeners[i] === listener){ |
| 68 | + listeners.splice(i, 1); |
| 69 | + } |
| 70 | + } |
| 71 | + }; |
| 72 | + |
| 73 | + return mql; |
| 74 | + }; |
47 | 75 | }());
|
0 commit comments