199 lines
4.9 KiB
JavaScript
199 lines
4.9 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
!function($) {
|
||
|
|
||
|
/**
|
||
|
* Interchange module.
|
||
|
* @module foundation.interchange
|
||
|
* @requires foundation.util.mediaQuery
|
||
|
* @requires foundation.util.timerAndImageLoader
|
||
|
*/
|
||
|
|
||
|
class Interchange {
|
||
|
/**
|
||
|
* Creates a new instance of Interchange.
|
||
|
* @class
|
||
|
* @fires Interchange#init
|
||
|
* @param {Object} element - jQuery object to add the trigger to.
|
||
|
* @param {Object} options - Overrides to the default plugin settings.
|
||
|
*/
|
||
|
constructor(element, options) {
|
||
|
this.$element = element;
|
||
|
this.options = $.extend({}, Interchange.defaults, options);
|
||
|
this.rules = [];
|
||
|
this.currentPath = '';
|
||
|
|
||
|
this._init();
|
||
|
this._events();
|
||
|
|
||
|
Foundation.registerPlugin(this, 'Interchange');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Initializes the Interchange plugin and calls functions to get interchange functioning on load.
|
||
|
* @function
|
||
|
* @private
|
||
|
*/
|
||
|
_init() {
|
||
|
this._addBreakpoints();
|
||
|
this._generateRules();
|
||
|
this._reflow();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Initializes events for Interchange.
|
||
|
* @function
|
||
|
* @private
|
||
|
*/
|
||
|
_events() {
|
||
|
$(window).on('resize.zf.interchange', Foundation.util.throttle(this._reflow.bind(this), 50));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Calls necessary functions to update Interchange upon DOM change
|
||
|
* @function
|
||
|
* @private
|
||
|
*/
|
||
|
_reflow() {
|
||
|
var match;
|
||
|
|
||
|
// Iterate through each rule, but only save the last match
|
||
|
for (var i in this.rules) {
|
||
|
if(this.rules.hasOwnProperty(i)) {
|
||
|
var rule = this.rules[i];
|
||
|
|
||
|
if (window.matchMedia(rule.query).matches) {
|
||
|
match = rule;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (match) {
|
||
|
this.replace(match.path);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets the Foundation breakpoints and adds them to the Interchange.SPECIAL_QUERIES object.
|
||
|
* @function
|
||
|
* @private
|
||
|
*/
|
||
|
_addBreakpoints() {
|
||
|
for (var i in Foundation.MediaQuery.queries) {
|
||
|
if (Foundation.MediaQuery.queries.hasOwnProperty(i)) {
|
||
|
var query = Foundation.MediaQuery.queries[i];
|
||
|
Interchange.SPECIAL_QUERIES[query.name] = query.value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks the Interchange element for the provided media query + content pairings
|
||
|
* @function
|
||
|
* @private
|
||
|
* @param {Object} element - jQuery object that is an Interchange instance
|
||
|
* @returns {Array} scenarios - Array of objects that have 'mq' and 'path' keys with corresponding keys
|
||
|
*/
|
||
|
_generateRules(element) {
|
||
|
var rulesList = [];
|
||
|
var rules;
|
||
|
|
||
|
if (this.options.rules) {
|
||
|
rules = this.options.rules;
|
||
|
}
|
||
|
else {
|
||
|
rules = this.$element.data('interchange').match(/\[.*?\]/g);
|
||
|
}
|
||
|
|
||
|
for (var i in rules) {
|
||
|
if(rules.hasOwnProperty(i)) {
|
||
|
var rule = rules[i].slice(1, -1).split(', ');
|
||
|
var path = rule.slice(0, -1).join('');
|
||
|
var query = rule[rule.length - 1];
|
||
|
|
||
|
if (Interchange.SPECIAL_QUERIES[query]) {
|
||
|
query = Interchange.SPECIAL_QUERIES[query];
|
||
|
}
|
||
|
|
||
|
rulesList.push({
|
||
|
path: path,
|
||
|
query: query
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.rules = rulesList;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update the `src` property of an image, or change the HTML of a container, to the specified path.
|
||
|
* @function
|
||
|
* @param {String} path - Path to the image or HTML partial.
|
||
|
* @fires Interchange#replaced
|
||
|
*/
|
||
|
replace(path) {
|
||
|
if (this.currentPath === path) return;
|
||
|
|
||
|
var _this = this,
|
||
|
trigger = 'replaced.zf.interchange';
|
||
|
|
||
|
// Replacing images
|
||
|
if (this.$element[0].nodeName === 'IMG') {
|
||
|
this.$element.attr('src', path).load(function() {
|
||
|
_this.currentPath = path;
|
||
|
})
|
||
|
.trigger(trigger);
|
||
|
}
|
||
|
// Replacing background images
|
||
|
else if (path.match(/\.(gif|jpg|jpeg|png|svg|tiff)([?#].*)?/i)) {
|
||
|
this.$element.css({ 'background-image': 'url('+path+')' })
|
||
|
.trigger(trigger);
|
||
|
}
|
||
|
// Replacing HTML
|
||
|
else {
|
||
|
$.get(path, function(response) {
|
||
|
_this.$element.html(response)
|
||
|
.trigger(trigger);
|
||
|
$(response).foundation();
|
||
|
_this.currentPath = path;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Fires when content in an Interchange element is done being loaded.
|
||
|
* @event Interchange#replaced
|
||
|
*/
|
||
|
// this.$element.trigger('replaced.zf.interchange');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Destroys an instance of interchange.
|
||
|
* @function
|
||
|
*/
|
||
|
destroy() {
|
||
|
//TODO this.
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Default settings for plugin
|
||
|
*/
|
||
|
Interchange.defaults = {
|
||
|
/**
|
||
|
* Rules to be applied to Interchange elements. Set with the `data-interchange` array notation.
|
||
|
* @option
|
||
|
*/
|
||
|
rules: null
|
||
|
};
|
||
|
|
||
|
Interchange.SPECIAL_QUERIES = {
|
||
|
'landscape': 'screen and (orientation: landscape)',
|
||
|
'portrait': 'screen and (orientation: portrait)',
|
||
|
'retina': 'only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx)'
|
||
|
};
|
||
|
|
||
|
// Window exports
|
||
|
Foundation.plugin(Interchange, 'Interchange');
|
||
|
|
||
|
}(jQuery);
|