Vanilla-lazyload: callback_exit() is not being called on non-image elements

Created on 24 Jun 2020  路  6Comments  路  Source: verlok/vanilla-lazyload

I have been using IntersectionObserver for other purposes. Then I decided to add LazyLoad to lazyload the images. Since LazyLoad also uses IO, I thought I might as well switch all my own IO event handlers/hooks to use LazyLoad. Everything works fine, except for callback_exit(). As it turns out, the IO detection on leaving works fine, it is just that it happened that I was using this on some other elements that have nothing to do with images. And so onExit() would ignore the event.

To reproduce, just create a div and have LazyLoad watch it with callback_enter() and callback_exit().

<div class="my-class">Some stuff</div>
var ll = new LazyLoad({
    elements_selector: ".my-class",
    callback_enter: callback_enter_fn,
    callback_exit: callback_exit_fn,
});

You will see it enters, but never exits :)

The fix is below. But I'm pretty sure there is a more "proper" way to do this and I hesitate to submit a PR without knowing the true effect of such a change.

--- lazyload.intersectionHandlers.js    2020-05-21 13:18:18.000000000 +0800
+++ lazyload.intersectionHandlers.NEW.js    2020-06-24 12:16:48.984638000 +0800
@@ -12,7 +12,8 @@
 };

 export const onExit = (element, entry, settings, instance) => {
-    if (hasEmptyStatus(element)) return; //Ignore the first pass, at landing
+    if ((element.tagName === "IMG") && (hasEmptyStatus(element))) return; //Ignore the first pass, at landing
     cancelLoadingIfRequired(element, entry, settings, instance);
     safeCallback(settings.callback_exit, element, entry, instance);
 };

I understand that this was never really LazyLoad's intention, I just thought I would save some code and avoid duplication in my own project.

Version: 16.1
Browser: Chrome (but any IO enabled browser really)

EDIT: Issue also exists in Version 17.0

Bug

All 6 comments

Hey @starfishpatkhoo, thanks for you thorough debugging.

If we applied the fix you are suggesting, you would get a lot of callback_exit called at landing, and it wouldn't work for iframes and videos.

I think the fix is to apply a status entered (I did this before, but then I deleted it) to all the observed elements, so the hasEmptyStatus(element) doesn't return true and the callback is then called.

export const onExit = (element, entry, settings, instance) => {
    if (hasEmptyStatus(element)) return; //Ignore the first pass, at landing
    cancelLoading(element, entry, settings, instance);
    safeCallback(settings.callback_exit, element, entry, instance);
};

Let me try this way.

Hello @starfishpatkhoo ,
this bug should be fixed now in 17.0.1.

Would you be able to double check?

@starfishpatkhoo please let me know if this worked for you.

Sorry @verlok working on some other high priority issue a.t.m. .. I will be able to get back to this and the other one on tuesday.. apologies :)

Works great, thanks @verlok! Yes, that's a good way to go about it to add a "entered" status, safer than checking the type of element. :)

Hey @starfishpatkhoo ,
I鈥檓 glad this solved!

Thank you again for reporting the bug.
Have a nice day!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zmrhaljiri picture zmrhaljiri  路  8Comments

brycewray picture brycewray  路  5Comments

vanloc0301 picture vanloc0301  路  6Comments

sendmenas picture sendmenas  路  6Comments

nicomollet picture nicomollet  路  4Comments