Nyoman Nyoman - 6 months ago 14
Javascript Question

HTML 5's <picture> lazy load (without jquery)

I've programmed a small lightbox for viewing images on my website. To keep the loading process fast I would like to "lazy load" the fullsize image. At the moment browsers always load the preview (test.jpg?size=520px) and the fullsize image (test.jpg).

Is there any simple solution to prevent browsers from loading the fullsize image until the image is clicked?


  • The website is only using minimal javascript - but I found no "no javascript" solution. Additionally I prefer a solution that doesn't require large html strings inside the .js file that will be added on mouse click.

  • Most lazy load scripts change only the attribute key inside the image tag. However, with HTML 5 this is now longer a useful approach. Maybe it is possible to change the
    <picture>
    tag (
    <picture>
    <<>>
    <picture-disabled>
    ) and prefetch the full size image?



HTML:

<div class="imagecc">
<picture onclick="lightboxshow('test004.jpg')">
<source type="image/webp" srcset="test004.webp?size=520px">
<img src="test.jpg?size=520px" alt="...">
</picture>
<p class="imgcaption">...</p>
</div>
<div id="test004.jpg" class="imageccbox" onclick="lightboxclose(this)">
<div class="imageccboxpicture">
<picture>
<source type="image/webp" srcset="test004.webp">
<img src="test.jpg">
</picture>
</div>
</div>


CSS:

.imageccbox {
display: none;
position: fixed;
z-index: 9999;
top: 0; left: 0;
width: 100%;
height: 100%;
background: linear-gradient(180deg, rgba(255,255,255,0.9), rgba(255,255,255,1));
text-align: center;}
.imageccbox:target {
background: rgba(255,255,255,0.8);
display: block;
outline: none;}
.imageccbox:target > .imageccboxpicture {opacity: 1.0;}
.imageccboxpicture {
margin-top: 5%;
opacity: 0.4;
transition: opacity 500ms linear;
cursor: none;}


JavaScript:

function lightboxshow(object) {
var imageccbox = document.getElementById(object);
imageccbox.style.display='block';
setTimeout(function() {imageccbox.getElementsByClassName("imageccboxpicture")[0].style.opacity = 1.0;}, 25);
window.location.hash = object;}

Answer

Consider using the <template> element. It's just a part of web components.

Essentially you stuff any content in <template> that you do not want the browser to load, and then move the content when you want it to be loaded. You make that change onload, or onclick, or whatever other event you like. Either way, it's not a lot of JavaScript to do and you don't need any libraries.

Take a look at this tutorial: Quick trick: using template to delay loading of images.

Older browsers that don't support the tag just won't get the lazy load benefit, so there is a nice progressive enhancement bonus there as well.

Another reference: http://webcomponents.org/articles/introduction-to-template-element/