Hi, great implementation of the blazy library. thank you!

I have a page the is dynamically loading content with ajax and I am wanting to run blazy once the new content is on the page. I have tried using Drupal.attachBehaviors(); and a variety of different options reusing code from blazy.load.js. Is there an easy way for me to attach Drupal.behaviors.blazy upon a succesful ajax call? thank you

Comments

lindsaywilson23 created an issue. See original summary.

gausarts’s picture

Status: Active » Postponed (maintainer needs more info)

Sorry for delay.

Basically I read this some time ago and I didn't immediately understand the actual issue. So I skipped.
If you could help me with more details I might be able to see the issue better.

Unless I missed the obvious, you don't need to do any extra effort to attach Blazy as it already uses Drupal.attachBehaviors().

Blazy was tried a lot with AJAX, at least using Views AJAX.
It has at least 4 working live examples at Slick Browser module.

gausarts’s picture

Status: Postponed (maintainer needs more info) » Fixed

You may want to try using Views AJAX, and see how it goes. Normally should just work.
If you do custom work, I am afraid I cannot help. You may have better luck in the forum, or Stack Exchange.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

lindsay.wils’s picture

Hello. Opening this one up again for some further discussion and examples of issues I am seeing.

I am using Blazy with images that are in a slick gallery. Even with 'Load invisible' checked, not all the images load, and as you scroll through, some images will not display, still showing the loading animation. If the user then scrolls the viewport, blazy.revalidate() is called and the image displays. While this is great, if the user doesnt scroll, it seems broken. What I would love to be able to do is call a Drupal behavior to revalidate blazy myself, on the slick event afterChange.

I have a similar issue using isotope. If a user scrolls to the top of my isotope listing, the first few load. If they then filter the listing, the content adjusts and some elements from lower on the page move to the top. At this point they just sit there spinning until the user scrolls, and even then, sometimes dont load. It would be great to be able to call a behavior to revalidate blazy on the layoutComplete event from isotope.

I have tried adding my own blazy calls, but this doubles up and causeing undesired effects.

I understand I can run Drupal.attachBehaviors(); on these events, but this isnt always ideal and seems overkill to call, when all I want to so is revalidate Blazy.

In blazy.load.js there is Drupal.behaviors.blazy.attach(), would it be feasible to add a new function in here to validate() that anyone can call as they please?

Or maybe there is another solution here that anyone else has come up with? Open to hearing any options here.

Thank you for your time :)

gausarts’s picture

Status: Closed (fixed) » Postponed (maintainer needs more info)

In blazy.load.js there is Drupal.behaviors.blazy.attach(), would it be feasible to add a new function in here to validate() that anyone can call as they please?

I am not sure if this is relevant to your need, as I don't see your code, but we have a sample to revalidate blazy here:
https://cgit.drupalcode.org/slick/tree/js/slick.load.js#n71
https://cgit.drupalcode.org/slick/tree/js/slick.load.js#n59

    t.on('setPosition.sl', function (e, slick) {
        setPosition(slick);

        // Revalidate Blazy.
        if (isBlazy && $src.length) {
          Drupal.blazy.init.revalidate();
        }
      });

Perhaps you can put Drupal.blazy.init.revalidate(); on the newly loaded content, and see if it makes any difference.
Alternatively you may want to trick Blazy to revalidate itself by triggering a slight window.scrollTo() which will not be noticeable to users, says 10 + current DOM position (elm.getBoundingClientRect().top).

lindsay.wils’s picture

My implementation is just a standard slick slider of images, but not using the Drupal Slick module.

Thanks very much for this, that is exactly what I am looking for, I had tried something along these lines, but not quite the same. This works perfectly, I call that function on afterChange and the new images now load as they slide in. Thank you :)

$('.slick.slideshow').slick({
                dots: true
            }).on('afterChange', function(){
                Drupal.blazy.init.revalidate();
            });
gausarts’s picture

Status: Postponed (maintainer needs more info) » Fixed

Glad you did it ;) Cheers!

lindsay.wils’s picture

Sorry to open up this again, but want to bring up another issue I am finding.

https://www.woodstockinn.com/do/events
Take this page as an example.

On initial page load, there are no nodes displaying that use a view mode with an image using a blazy display, for this reason, the blazy script is not being loaded by Blazy module.

After my ajax calls, Drupal.blazy.init.revalidate(); is obviously logging an error, as Drupal.blazy doesnt exist, as the script was never loaded onto the page.

Drupal.attachBehaviors(); is also not adding the Blazy js functions, because the initial page load never had blazy displays and it was never loaded into the Drupal behaviors object.

I have tried loading the script myself through a variety of methods like

if(typeof Drupal.blazy === 'undefined'){

            let script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = '/modules/contrib/blazy/js/dblazy.min.js';
            document.getElementsByTagName('head')[0].appendChild(script);

            script.src = '/modules/contrib/blazy/js/blazy.load.min.js';
            document.getElementsByTagName('head')[0].appendChild(script);

        }

But I cannot get it to work. Can anyone think of any workaround to this scenario?

Thanks in advance.

gausarts’s picture

You sounded loading libraries using JS.

Consider using #attached property in your render array:
https://cgit.drupalcode.org/blazy/tree/blazy.api.php#n92

And manually invoke blazy.manager service with attach method in your main container element (not individual blazy element). The main container may be present all the time on the page, as you expected, and thus guarantees loading the libraries.

This also has been proven to work such as with Views AJAX loaded Blazy blocks or pages for example.

gausarts’s picture

If you don't use render array, Drupal 8 made it easy to attach local libraries via preprocess, or TWIG:
https://www.drupal.org/node/2456753

Or if you don't mind ~1KB gzip of blazy, use your theme to load Blazy globally. Adding a dependency to your script on blazy/load should do.

lindsay.wils’s picture

Ahh thank you so much! I dont know why I was trying to over complicate this so much with that hack, didnt even think of libraries, very silly.

I have just added the dependency to blazy/load on my main js and all is good :)

gausarts’s picture

You are not alone ;) I myself missed the obvious quite often.
Glad you did it!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

gonssal’s picture

Sorry for commenting on this closed issue, but I thought it would be better than opening a new one.

I'm loading a page where an entity is shown in a boostrap 4 modal, by using the css class use-ajax. The entity has an images field that uses the Slick slider formatter. When loaded normally, it works without any problem, but when loaded in a modal, the slider images never load.

Upon inspecting the code, I can see that the slider is initalized (the slick-initialized class is added), but the images are never loaded. If I check any of the slider items, I can see that every .slick__slide has the property visibility: hidden set, which I guess should be removed by Blazy when showing the image. If I manually remove this property, the Blazy image loading spinner is shown.

I tried running Drupal.blazy.init.revalidate(); when the modal is loaded but nothing happens. I've been battling with this for hours now, and I'm honestly out of options, so any idea on what might be happening would be nice.

Is there any way to disable Blazy when using the Slick slider module?

No errors on the javascript console by the way.

gausarts’s picture

Is there any way to disable Blazy when using the Slick slider module?

Yes, edit your optionset under Lazyload option.

...I can see that every .slick__slide has the property visibility: hidden set, which I guess should be removed by Blazy when showing the image.

Blazy doesn't do it. If Slick does, you might want to reinit on your loaded content either manually or using drupal attach mentioned above.