0

I am having a problem configuring jQuery.Lazy() to work with images that have been appended with a hash. In asp.net core Razor pages, you can use a Image Tag Helper so that the server appends the src with a hash that is checked/updated if the image is ever modified. The syntax is pretty straight forward:

For an <img>, simply add asp-append-version="true" and the server will auto-append the hash to the src. i.e.:

<img src="/images/Photo.jpg" asp-append-version="true">

Which will show up in the browser as:

<img src="/images/Photo.jpg?v=4jjcjhwsV9YZ1K8lXgg_50rci1ju_mNaz-HABqCvPFk">

The problem is: it can ONLY be applied to the src, and hence lies the issue.

So when I add .lazy to the <img> like so:

<img class="lazy" src="/images/PhotoPlaceholder.png" data-src="/images/Photo.jpg" asp-append-version="true">

.lazy works great (with the image fading in as expected), BUT the HTML is now this:

<img class="lazy" src="/images/PhotoPlaceholder.png?v=4jjcjhwsV9YZ1K8lXgg_50rci1ju_mNaz-HABqCvPFk" data-src="/images/Photo.jpg">

Obviously, now the hash will NOT work because it's attached to PhotoPlaceholder.png instead of Photo.jpg. So, how do I configure jQuery.Lazy() to work with the hash? With jQuery.Lazy() or some extra jquery? BTW: I already tried playing with the 'attribute' option, etc. but can't get it to work. Anyone have an idea on how to solve this? I CANNOT be the only one who has run into this issue.

Furthermore, is this even possible? Or do I just have to pick one feature over the other? I need the version hash check because the images may be changed by users and therefore they need to be auto-refreshed (instead of everyone having to do a cache-emptying reload by hitting <ctrl> F5 on the page). I also understand browsers use/need the <src> to display the image (and not much can be done from that perspective), but I was hoping someone may have come up with a work-around to solve this dilemma.

My jQuery.Lazy() is pretty straight forward:

$(".lazy").Lazy({
    effect: 'fadeIn',
    effectTime: 1000
});

Thanks for any help/suggestions... :)

1
  • 1
    Please refer this answer to extend the method to implement the assignment of data-src. Commented Jan 24, 2022 at 9:33

1 Answer 1

0

As it turns out, there are 2 ways to handle this:

Solution 1:
Thanks to some help from @eisbehr, there is a way to append the data-src on the client using a hidden <link> element, as so:

<link class="hide-control" id="source-img-1" href="/images/Photo.jpg" asp-append-version="true">
<img class="lazy" id="img-1" data-loader="hashedImageLoader" src="/images/PhotoPlaceholder.png" data-src="/images/Photo.jpg" asp-append-version="true">

That will produce the following HTML markup:

<link class="hide-control" id="source-img-1" href="/images/Photo.jpg?v=AAnmbJAusQ-go5lyg9qCes4WGj8oWsp4eGH78CKKUPA">
<img class="lazy" id="img-1" data-loader="hashedImageLoader" src="/images/PhotoPlaceholder.png?v=4jjcjhwsV9YZ1K8lXgg_50rci1ju_mNaz-HABqCvPFk" data-src="/images/Photo.jpg">

And then using Jquery, update the <img> using the href from the <link> like this:

$('.lazy').Lazy({
    effect: 'fadeIn',
    effectTime: 1000,
    beforeLoad: element => {
        let source = $('#source-' + element.attr('id')).attr('href');
        element.attr('data-src', source);
    }
});

Solution 2:
The second way (and perhaps preferred as suggested by @JasonPan) is to append the data-src with the asp-append-version on the server using asp.net core. In the page (or Partial View if retrieving via AJAX), simply add:

@using Microsoft.Extensions.DependencyInjection;

var versionProvider = Context.RequestServices.GetRequiredService<IFileVersionProvider>();

// Loop as needed for each file
PathFile = "/images/Photo.jpg";
PathFileWithHash = versionProvider.AddFileVersionToPath(Context.Request.Path, PathFile);
<img class="lazy" src="/images/PhotoPlaceholder.png" data-src="@PathFileWithHash" asp-append-version="true">

And on the client, simply call .lazy:

$(".lazyLoadImage").Lazy({
    effect: "fadeIn",
    effectTime: 1000
});

Both solutions work as expected so take your pick... :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.