Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

srcset support #337

Open
strarsis opened this issue Nov 13, 2017 · 5 comments
Open

srcset support #337

strarsis opened this issue Nov 13, 2017 · 5 comments

Comments

@strarsis
Copy link

In case an <img> with srcset/sizes is provided, will it just work - or are there any JavaScript handlers that lazy load the image? If so, is this handled by Featherlight, too? Most CMS and sites use srcset/sizes now.

@marcandre
Copy link
Collaborator

I'm afraid it's not supported by the image content filter, but it definitely should. PR very welcome...

@bradleysepos
Copy link

The way I'm handling this might be of use to someone, and potentially could be turned into a patch or pull request.

HTML:

<figure>
  <a href="foo.png">
    <img src="foo.png" srcset="foo.png 1x, foo@2x.png 2x, foo@3x.png 3x" alt="foo" />
  </a>
  <figcaption>A picture of foo.</figcaption>
</figure>

Old JS:

$('figure > a:has(img)').featherlight({type: 'image'});

New JS (srcset-aware):

$.featherlight.contentFilters.image2 = {
  regex: /\.(png|jpg|jpeg|gif|tiff?|bmp|svg)(\?\S*)?$/i,
  process: function(url){
    var self = this,
      deferred = $.Deferred(),
      img = new Image(),
      $img = $('<img src="'+url+'" alt="" class="'+self.namespace+'-image" />');
    var srcset = $(this.$currentTarget[0]).attr('data-srcset');
    if (srcset.length > 0) {
      $img = $('<img src="'+url+'" srcset="'+srcset+'" alt="" class="'+self.namespace+'-image" />');
    };
    img.onload  = function() {
      /* Store naturalWidth & height for IE8 */
      $img.naturalWidth = img.width; $img.naturalHeight = img.height;
      deferred.resolve( $img );
    };
    img.onerror = function() { deferred.reject($img); };
    img.src = url;
    return deferred.promise();
  }
};
$.featherlight.defaults.contentFilters.unshift('image2');

$.featherlight.defaults.onResize = function(){
  $(this.$content[0]).css('max-width', this.$content[0].naturalWidth);
  $(this.$content[0]).css('max-height', this.$content[0].naturalHeight);
};

$('figure > a:has(img)').each(function(){
  var srcset = $(this).children('img').first().attr('srcset');
  if (srcset.length > 0){
    $(this).attr('data-srcset', srcset);
  }
  $(this).featherlight({type: 'image2'});
});
  • The content filter named image2 is a clone of the inbuilt image with a simple modification: it uses the data-srcset attribute on the a (if present) to construct the lightboxed image with a matching srcset attribute.
  • It is simple enough to create the data-srcset on the parent a from the child image's srcset value.
  • The onResize function limits the maximum size of the lightboxed image so that the higher pixel density assets display in the same dimensions.
  • Note that all Featherlighted figure > a in my html are guaranteed to have a single child img.

Thanks to the Featherlight crew for making it extensible. 👏

@whatsnewsisyphus
Copy link

Fancybox v3 has a pretty ok implementation with data-srcset on the child elements

@strarsis
Copy link
Author

@whatsnewsisyphus: Sadly it got licensing that is not free for commercial sites, hence an OpenSource solution would be nice.

@whatsnewsisyphus
Copy link

I know, but it is open source and provides an example implementation if somebody needs inspiration to do so for featherlight.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants