Skip to content
New issue

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

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

Already on GitHub? Sign in 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.

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

No branches or pull requests

4 participants