代码之家  ›  专栏  ›  技术社区  ›  Pete Irfan TahirKheli

IE11 PolyFill基于图片源集加载背景图像

  •  0
  • Pete Irfan TahirKheli  · 技术社区  · 6 年前

    我已经为IE编写了以下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.prop('currentSrc') 本来是要得到它的,但在IE11中似乎不起作用(如果你在Chrome中查看它,它会加载正确的背景图像)

    1 回复  |  直到 6 年前
        1
  •  0
  •   Pete Irfan TahirKheli    6 年前

    这是因为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)
      }
    });