2025-01-12 04:36:52 +08:00

154 lines
4.9 KiB
JavaScript

/* imgsrcset - Img srcset polyfill for resolution responsive images. Authors & copyright (c) 2012: WebLinc, David Knight. */
// Imgsrcset
(function(win) {
'use strict';
var _viewport = win.document.documentElement,
_srcsetID = 0,
_srcsets = [],
_eventPrefix = '',
_addEvent = win.addEventListener || (_eventPrefix = 'on') && win.attachEvent,
_removeEvent = win.removeEventListener || win.detachEvent,
_srcExpr = /[^\s]+/g,
_digitExpr = /[0-9\.]+/g,
_timer = 0,
/*
_matches
*/
_matches = function(srcset) {
var srcList = (srcset.indexOf(',') !== -1 && srcset.split(',')) || [srcset],
srcIndex = srcList.length - 1,
srcLength = srcIndex,
list = null,
listIndex = 0,
src = '',
media = '';
if (srcIndex < 0) {
return;
}
do {
var list = srcList[srcLength - srcIndex].match(_srcExpr) || [],
listIndex = list.length;
while (listIndex--) {
var item = list[listIndex],
feature = 0,
digits = 0;
if (listIndex > 0) {
feature = (item.indexOf('w') !== -1 && (win.innerWidth || _viewport.clientWidth)) ||
(item.indexOf('h') !== -1 && (win.innerHeight || _viewport.clientHeight)) ||
(item.indexOf('x') !== -1 && (win.devicePixelRatio || 1));
digits = Number(item.match(_digitExpr));
if (feature && digits && digits > feature) {
break;
}
} else {
src = item;
media = srcList[srcIndex];
}
}
} while (srcIndex--);
return (src && media && {src: src, media: media}) || false;
},
/*
watch
*/
_watch = function(evt) {
clearTimeout(_timer);
_timer = setTimeout(function() {
var srcset = null,
srcsetIndex = _srcsetID - 1,
srcsetLength = srcsetIndex,
match = false;
do {
srcset = _srcsets[srcsetLength - srcsetIndex];
// If img element does not have a parent, remove array index to prevent caching
if (!srcset.element.parentNode) {
_srcsetID--;
srcset.splice(srcsetIndex, 1);
continue;
}
match = _matches(srcset.media);
if (match && (srcset.matches !== match.media)) {
srcset.matches = match.media;
srcset.element.src = match.src;
} else if (!match) {
srcset.matches = false;
srcset.src && (srcset.element.src = srcset.src);
}
} while(srcsetIndex--);
}, 10);
},
/*
init
*/
_init = function() {
_removeEvent(_eventPrefix + 'load', _init);
win.Imgsrcset.parse();
_watch();
// Processes '_srcsets' array and determines which source to use
// '_watch' will clear out any images from the array that do not have parents, which should eliminate element caching
_addEvent(_eventPrefix + 'resize', _watch);
_addEvent(_eventPrefix + 'orientationchange', _watch);
};
/*
imgsrcset
*/
win.Imgsrcset = {
/*
parse
Called on '_init' and can also be called if new images are added/removed
*/
parse: function() {
_srcsets = [];
var imgs = win.document.getElementsByTagName('img') || [],
imgIndex = imgs.length - 1,
imgLength = imgIndex,
img = null,
srcset = '';
do {
img = imgs[imgLength - imgIndex];
srcset = img.getAttribute('srcset') || '';
if (!srcset) {
continue;
}
_srcsetID = _srcsets.push({
element : img,
media : srcset,
matches : false,
src : img.getAttribute('src') || ''
});
} while(imgIndex--);
}
};
// Set up listeners
_addEvent(_eventPrefix + 'load', _init);
})(window);