(more js) |
|||
Line 1: | Line 1: | ||
<html> | <html> | ||
− | /* | + | <script> |
− | + | /* breakpoints.js v0.1-dev | @ajlkn | MIT licensed */ | |
− | + | ||
− | + | ||
− | */ | + | |
+ | var breakpoints = (function() { "use strict"; var _ = { | ||
+ | |||
+ | /** | ||
+ | * List. | ||
+ | * @var {array} | ||
+ | */ | ||
+ | list: null, | ||
+ | |||
+ | /** | ||
+ | * Media cache. | ||
+ | * @var {object} | ||
+ | */ | ||
+ | media: {}, | ||
+ | |||
+ | /** | ||
+ | * Events. | ||
+ | * @var {array} | ||
+ | */ | ||
+ | events: [], | ||
+ | |||
+ | /** | ||
+ | * Initialize. | ||
+ | * @param {array} list List. | ||
+ | */ | ||
+ | init: function(list) { | ||
+ | |||
+ | // Set list. | ||
+ | _.list = list; | ||
+ | |||
+ | // Add event listeners. | ||
+ | window.addEventListener('resize', _.poll); | ||
+ | window.addEventListener('orientationchange', _.poll); | ||
+ | window.addEventListener('load', _.poll); | ||
+ | window.addEventListener('fullscreenchange', _.poll); | ||
+ | |||
+ | }, | ||
+ | |||
+ | /** | ||
+ | * Determines if a given query is active. | ||
+ | * @param {string} query Query. | ||
+ | * @return {bool} True if yes, false if no. | ||
+ | */ | ||
+ | active: function(query) { | ||
+ | |||
+ | var breakpoint, op, media, | ||
+ | a, x, y, units; | ||
+ | |||
+ | // Media for this query doesn't exist? Generate it. | ||
+ | if (!(query in _.media)) { | ||
+ | |||
+ | // Determine operator, breakpoint. | ||
+ | |||
+ | // Greater than or equal. | ||
+ | if (query.substr(0, 2) == '>=') { | ||
+ | |||
+ | op = 'gte'; | ||
+ | breakpoint = query.substr(2); | ||
+ | |||
+ | } | ||
+ | |||
+ | // Less than or equal. | ||
+ | else if (query.substr(0, 2) == '<=') { | ||
+ | |||
+ | op = 'lte'; | ||
+ | breakpoint = query.substr(2); | ||
+ | |||
+ | } | ||
+ | |||
+ | // Greater than. | ||
+ | else if (query.substr(0, 1) == '>') { | ||
+ | |||
+ | op = 'gt'; | ||
+ | breakpoint = query.substr(1); | ||
+ | |||
+ | } | ||
+ | |||
+ | // Less than. | ||
+ | else if (query.substr(0, 1) == '<') { | ||
+ | |||
+ | op = 'lt'; | ||
+ | breakpoint = query.substr(1); | ||
+ | |||
+ | } | ||
+ | |||
+ | // Not. | ||
+ | else if (query.substr(0, 1) == '!') { | ||
+ | |||
+ | op = 'not'; | ||
+ | breakpoint = query.substr(1); | ||
+ | |||
+ | } | ||
+ | |||
+ | // Equal. | ||
+ | else { | ||
+ | |||
+ | op = 'eq'; | ||
+ | breakpoint = query; | ||
+ | |||
+ | } | ||
+ | |||
+ | // Build media. | ||
+ | if (breakpoint && breakpoint in _.list) { | ||
+ | |||
+ | a = _.list[breakpoint]; | ||
+ | |||
+ | // Range. | ||
+ | if (Array.isArray(a)) { | ||
+ | |||
+ | x = parseInt(a[0]); | ||
+ | y = parseInt(a[1]); | ||
+ | |||
+ | if (!isNaN(x)) | ||
+ | units = a[0].substr(String(x).length); | ||
+ | else if (!isNaN(y)) | ||
+ | units = a[1].substr(String(y).length); | ||
+ | else | ||
+ | return; | ||
+ | |||
+ | // Max only. | ||
+ | if (isNaN(x)) { | ||
+ | |||
+ | switch (op) { | ||
+ | |||
+ | // Greater than or equal (>= 0 / anything) | ||
+ | case 'gte': | ||
+ | media = 'screen'; | ||
+ | break; | ||
+ | |||
+ | // Less than or equal (<= y) | ||
+ | case 'lte': | ||
+ | media = 'screen and (max-width: ' + y + units + ')'; | ||
+ | break; | ||
+ | |||
+ | // Greater than (> y) | ||
+ | case 'gt': | ||
+ | media = 'screen and (min-width: ' + (y + 1) + units + ')'; | ||
+ | break; | ||
+ | |||
+ | // Less than (< 0 / invalid) | ||
+ | case 'lt': | ||
+ | media = 'screen and (max-width: -1px)'; | ||
+ | break; | ||
+ | |||
+ | // Not (> y) | ||
+ | case 'not': | ||
+ | media = 'screen and (min-width: ' + (y + 1) + units + ')'; | ||
+ | break; | ||
+ | |||
+ | // Equal (<= y) | ||
+ | default: | ||
+ | media = 'screen and (max-width: ' + y + units + ')'; | ||
+ | break; | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | // Min only. | ||
+ | else if (isNaN(y)) { | ||
+ | |||
+ | switch (op) { | ||
+ | |||
+ | // Greater than or equal (>= x) | ||
+ | case 'gte': | ||
+ | media = 'screen and (min-width: ' + x + units + ')'; | ||
+ | break; | ||
+ | |||
+ | // Less than or equal (<= inf / anything) | ||
+ | case 'lte': | ||
+ | media = 'screen'; | ||
+ | break; | ||
+ | |||
+ | // Greater than (> inf / invalid) | ||
+ | case 'gt': | ||
+ | media = 'screen and (max-width: -1px)'; | ||
+ | break; | ||
+ | |||
+ | // Less than (< x) | ||
+ | case 'lt': | ||
+ | media = 'screen and (max-width: ' + (x - 1) + units + ')'; | ||
+ | break; | ||
+ | |||
+ | // Not (< x) | ||
+ | case 'not': | ||
+ | media = 'screen and (max-width: ' + (x - 1) + units + ')'; | ||
+ | break; | ||
+ | |||
+ | // Equal (>= x) | ||
+ | default: | ||
+ | media = 'screen and (min-width: ' + x + units + ')'; | ||
+ | break; | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | // Min and max. | ||
+ | else { | ||
+ | |||
+ | switch (op) { | ||
+ | |||
+ | // Greater than or equal. | ||
+ | case 'gte': | ||
+ | media = 'screen and (min-width: ' + x + units + ')'; | ||
+ | break; | ||
+ | |||
+ | // Less than or equal. | ||
+ | case 'lte': | ||
+ | media = 'screen and (max-width: ' + y + units + ')'; | ||
+ | break; | ||
+ | |||
+ | // Greater than. | ||
+ | case 'gt': | ||
+ | media = 'screen and (min-width: ' + (y + 1) + units + ')'; | ||
+ | break; | ||
+ | |||
+ | // Less than. | ||
+ | case 'lt': | ||
+ | media = 'screen and (max-width: ' + (x - 1) + units + ')'; | ||
+ | break; | ||
+ | |||
+ | // Not. | ||
+ | case 'not': | ||
+ | media = 'screen and (max-width: ' + (x - 1) + units + '), screen and (min-width: ' + (y + 1) + units + ')'; | ||
+ | break; | ||
+ | |||
+ | // Equal. | ||
+ | default: | ||
+ | media = 'screen and (min-width: ' + x + units + ') and (max-width: ' + y + units + ')'; | ||
+ | break; | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | // String. | ||
+ | else { | ||
+ | |||
+ | // Missing a media type? Prefix with "screen". | ||
+ | if (a.charAt(0) == '(') | ||
+ | media = 'screen and ' + a; | ||
+ | |||
+ | // Otherwise, use as-is. | ||
+ | else | ||
+ | media = a; | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | // Cache. | ||
+ | _.media[query] = (media ? media : false); | ||
+ | |||
+ | } | ||
+ | |||
+ | return ( | ||
+ | _.media[query] === false | ||
+ | ? false | ||
+ | : window.matchMedia(_.media[query]).matches | ||
+ | ); | ||
+ | |||
+ | }, | ||
+ | |||
+ | /** | ||
+ | * Registers an event. | ||
+ | * @param {string} query Query. | ||
+ | * @param {function} handler Handler. | ||
+ | */ | ||
+ | on: function(query, handler) { | ||
+ | |||
+ | // Register event. | ||
+ | _.events.push({ | ||
+ | query: query, | ||
+ | handler: handler, | ||
+ | state: false | ||
+ | }); | ||
+ | |||
+ | // Query active *right now*? Call handler. | ||
+ | if (_.active(query)) | ||
+ | (handler)(); | ||
+ | |||
+ | }, | ||
+ | |||
+ | /** | ||
+ | * Polls for events. | ||
+ | */ | ||
+ | poll: function() { | ||
+ | |||
+ | var i, e; | ||
+ | |||
+ | // Step through events. | ||
+ | for (i=0; i < _.events.length; i++) { | ||
+ | |||
+ | // Get event. | ||
+ | e = _.events[i]; | ||
+ | |||
+ | // Active? | ||
+ | if (_.active(e.query)) { | ||
+ | |||
+ | // Hasn't been called yet? | ||
+ | if (!e.state) { | ||
+ | |||
+ | // Mark as called. | ||
+ | e.state = true; | ||
+ | |||
+ | // Call handler. | ||
+ | (e.handler)(); | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | // Otherwise ... | ||
+ | else { | ||
+ | |||
+ | // Previously called? | ||
+ | if (e.state) { | ||
+ | |||
+ | // Unmark as called. | ||
+ | e.state = false; | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | }, | ||
+ | |||
+ | }; function __(list) { _.init(list); }; __._ = _; __.on = function(query, handler) { _.on(query, handler); }; __.active = function(query) { return _.active(query); }; return __; })(); | ||
+ | |||
+ | // UMD Wrapper (github.com/umdjs/umd/blob/master/returnExports.js | @umdjs + @nason) | ||
+ | (function(root, factory) { | ||
+ | |||
+ | // AMD. | ||
+ | if (typeof define === 'function' && define.amd) | ||
+ | define([], factory); | ||
+ | |||
+ | // Node. | ||
+ | else if (typeof exports === 'object') | ||
+ | module.exports = factory(); | ||
+ | |||
+ | // Breakpoints global. | ||
+ | else | ||
+ | root.breakpoints = factory(); | ||
+ | |||
+ | }(this, function() { return breakpoints; })); | ||
+ | </script> | ||
<script> | <script> | ||
(function($) { | (function($) { |
Revision as of 21:27, 17 October 2019