[英]ie11 polyfill to load background image based on picture sourceset
我為編寫了以下polyfill,以便可以使用CSS object-fit
:
const $images = $('.object-fit'); const replacementClass = 'object-fit-replacement'; if ($images.length) { $images.each(function(index, item) { const $image = $(item); // this code will not run in IE if image is in the cache $image.on('load', function(e) { makeDiv(e.currentTarget); }); // this code will run if image is already in the cache if (item.complete) { makeDiv(item); } }); } function makeDiv(image) { const $image = $(image); const $picture = $image.closest('picture'); let $div; let $parent; let imageSource; if ($picture.length) { $parent = $picture.parent(); imageSource = $image.prop('currentSrc') || image.src; } else { $parent = $image.parent(); imageSource = image.src; } $div = $parent.find('.' + replacementClass); if (!$div.length) { $div = $('<div class="' + replacementClass + '"></div>'); $parent.append($div); } $div.css('background-image', 'url(' + imageSource + ')'); $picture.hide(); $image.hide(); }
.object-fit-replacement { /* for test only */ background-size:cover; width:100vw; height:100vh; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <picture> <source srcset="https://via.placeholder.com/300x100" media="(max-width:768px)"> <source srcset="https://via.placeholder.com/600x300" media="(min-width:768px)"> <img src="https://via.placeholder.com/200x200" alt="Test" class="image object-fit"> </picture>
但是,它似乎僅從image標簽加載實際的圖像源。 有沒有辦法尊重當前資源(取自圖片標簽中正確的媒體查詢)-我以為$image.prop('currentSrc')
是要獲取它的,但似乎在ie11中不起作用(如果您使用的是chrome,則會加載正確的背景圖片)
這是由於ie11無法處理像素。 最后,由於我知道我們網站上所有圖片元素的斷點(並且它們不會更改,因為它們是由服務器端幫助程序創建的),所以我添加了一些jquery以獲取正確的源從圖片標簽中:
import $ from 'jquery';
import elementHelper from '../helpers/element-helper';
import throttle from 'lodash/throttle';
$(() => {
const $images = $('.object-fit');
const replacementClass = 'object-fit-replacement';
const $window = $(window);
if ($images.length) {
$images.each((index, item) => {
const $image = $(item);
let imageLoaded = false;
// this code will not run in IE if image is in the cache
$image.on('load', e => {
if (!imageLoaded) {
makeDiv(e.currentTarget);
imageLoaded = true;
}
});
// this code will run if image is already in the cache
if (item.complete && !imageLoaded) {
makeDiv(item);
imageLoaded = true;
}
});
}
$window.on('resize', throttle(() => {
$(`.${replacementClass}`).each((index, item) => {
const $picture = $(item).prev('picture');
console.log('resize', $picture.length)
if ($picture.length) {
$div.css('background-image', `url(${getPictureSource($picture)})`);
}
});
}, 100));
function makeDiv(image) {
const $image = $(image);
const $picture = $image.closest('picture');
let $div;
let $parent;
let imageSource;
if ($picture.length) {
$parent = $picture.parent();
imageSource = getImageSource($picture, $image);
} else {
$parent = $image.parent();
imageSource = image.src;
}
$div = $parent.find(`.${replacementClass}`);
if (!$div.length) {
$div = $(elementHelper.createElement('div', replacementClass));
$parent.append($div);
}
$div.css('background-image', `url(${imageSource})`);
$picture.hide();
$image.hide();
}
function getImageSource($picture, $image) {
const imageSource = $image.prop('currentSrc');
if (imageSource) {
return imageSource;
} else {
return getPictureSource($picture);
}
}
function getPictureSource($picture) {
// this assumes that the image helper has created the object fit picture tag and is using the standard 5 media queries
const $sources = $picture.children('source');
if ($sources.length === 5) {
const windowWidth = $window.outerWidth();
if (windowWidth < 380) {
return $sources.eq(0).attr('srcset');
} else if (windowWidth >= 380 && windowWidth < 767) {
return $sources.eq(1).attr('srcset');
} else if (windowWidth >= 767 && windowWidth < 1200) {
return $sources.eq(2).attr('srcset');
} else if (windowWidth >= 1200 && windowWidth < 1600) {
return $sources.eq(3).attr('srcset');
} else {
return $sources.eq(4).attr('srcset');
}
}
return $sources.last().attr('srcset'); // this assumes sources are done normally with desktop largest last (default to dektop)
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.