12

masonry infinite scroll append html5 videos overlapping

i am currently using imagesLoaded library which checks whether images are loaded then calls masonry.

But it was not working with html5 video tag, because of this videos gets overlapped on one another.

so i changed calling masonry from document.ready to window.load and removed call to imagesLoaded on initial loading i.e. from this

$(document).ready(function(){

    var $container = $('#media');
    // layout Masonry again after all images have loaded
    $container.imagesLoaded( function() {

      $container.masonry({
          "columnWidth": "." + "col-sm-2",
          itemSelector: '.item',
          gutter: 0,
        });
      $('.item').css('opacity', '1.0');
    });

});

to this

$(window).load(function(){
        var $container = $('#media');

          $container.masonry({
              "columnWidth": "." + "col-sm-2",
              itemSelector: '.item',
              gutter: 0,
            });
          $('.item').css('opacity', '1.0');
});

now html5 videos in masonry are not overlapping, and are rendering perfectly on page's first load i.e. initial load, but as i am also using infinite-scroll which adds more images/videos on scrolling page down, so when new videos are being added to container they are being overlapped , this behavior is caused by early running of masonry before all the video elements are being loaded as imagesloaded cant check the videos loaded.

this is the code.

$(document).ready(function(){
    var $container = $('#media');
    var no_more_media = "<?= Lang::get('lang.no_more_to_load') ?>";
    var loading_more_media = "<?= Lang::get('lang.loading_more_media') ?>";

    $container.imagesLoaded(function(){
            $container.masonry();
        });

$container.infinitescroll({
        loading: {
            finished: undefined,
            finishedMsg: "<p>" + no_more_media + "</p>",
            img: "data:image/gif;base64,R0lGODlhAQABAHAAACH5BAUAAAAALAAAAAABAAEAAAICRAEAOw==",
            msg: null,
            msgText: "<div class='loading'><i></i><i></i><i></i></div><p>" + loading_more_media + "</p>",
            selector: null,
            speed: 'fast',
            start: undefined,
        },
        navSelector  : "ul.pagination",            
                       // selector for the paged navigation (it will be hidden)
        nextSelector : "ul.pagination a:first",    
                       // selector for the NEXT link (to page 2)
        itemSelector : ".container #media .item",
        animate: false,
        bufferPx: 160,
      },

      function( newElements ) {
         // hide new items while they are loading
        //var $newElems = 
        $.each($(newElements), function(index, value){
            item_click_events($(value));
        });

            $( newElements ).css({ opacity: 0 });

            $(newElements).imagesLoaded(function(){
               var $newElems = $( newElements );
               $newElems.animate({ opacity: 1 });
               $container.masonry( 'appended', $newElems, true);
            }
            );

      });
});

i have tried changing document.ready to window.load in above code too, and removing running imagesloaded altogether, but its not working with infinitescroll.,

e.g. modified code

$(window).load(function(){
    var $container = $('#media');
    var no_more_media = "<?= Lang::get('lang.no_more_to_load') ?>";
    var loading_more_media = "<?= Lang::get('lang.loading_more_media') ?>";

            $container.masonry();

    $container.infinitescroll({
        loading: {
            finished: undefined,
            finishedMsg: "<p>" + no_more_media + "</p>",
            img: "data:image/gif;base64,R0lGODlhAQABAHAAACH5BAUAAAAALAAAAAABAAEAAAICRAEAOw==",
            msg: null,
            msgText: "<div class='loading'><i></i><i></i><i></i></div><p>" + loading_more_media + "</p>",
            selector: null,
            speed: 'fast',
            start: undefined,
        },
        navSelector  : "ul.pagination",            
                       // selector for the paged navigation (it will be hidden)
        nextSelector : "ul.pagination a:first",    
                       // selector for the NEXT link (to page 2)
        itemSelector : ".container #media .item",
        animate: false,
        bufferPx: 160,
      },

      function( newElements ) {
         // hide new items while they are loading
        //var $newElems = 
        $.each($(newElements), function(index, value){
            item_click_events($(value));
        });

            $( newElements ).css({ opacity: 0 });

               var $newElems = $( newElements );
               $newElems.animate({ opacity: 1 });
               $container.masonry( 'appended', $newElems, true);

      });
});

there is another way i can solve this overlapping issue, by specifying video width and height, but as its responsive design, specifying video width and height breaks the responsiveness.

so my question is , is there any js library simmilar to imagesloaded which makes sure all videos are loaded and then i can call to masonry ? or how can i make sure the videos wont get overlapped on infinitescroll ?


update 1 :

i have tried many techniques, for infinitescroll

$(newElements).load(function(){
   var $newElems = $( newElements );
   $newElems.animate({ opacity: 1 });
   $container.masonry( 'appended', $newElems, true);
});

doesnt loads new content after pagescroll.

$(window).load(function(){
   var $newElems = $( newElements );
   $newElems.animate({ opacity: 1 });
   $container.masonry( 'appended', $newElems, true);
});

doesnt loads new content after pagescroll.

   var $newElems = $( newElements );
   $newElems.animate({ opacity: 1 });
   $container.masonry( 'appended', $newElems, true);

overlaps video content

so i have came up with calling infinite-scroll early and slowing down the container.masonry by 3 seconds which is working perfectly for now., but still waiting for proper solution.

e.g.

bufferPx: 700,

setTimeout(function(){
       var $newElems = $( newElements );
       $newElems.animate({ opacity: 1 });
       $container.masonry( 'appended', $newElems, true);
}, 3000);

above is delaying running masonry by 3 seconds.

i tried looking for something like window.load for div, but there is none, so my best option is check whether all the videos and images are loaded and then call masonry after calling infinite-scroll


added working demo http://plnkr.co/edit/46YzHBJ7eFAXfsPqZB1q you can see the issue, by clicking run and scrolling down.

  • Add a fiddle or a code snippet and I ( or someone else ), will fix it. – Willem D'Haeseleer Aug 09 '16 at 05:03
  • A fiddle would definitely be the best result and most valuable to the question. Adding external links is generally discouraged because of "link rot". But if you really can't add a fiddle a link might be ok. I don't think there is a policy against NSFW links. – Willem D'Haeseleer Aug 09 '16 at 05:14
  • added working demo http://plnkr.co/edit/46YzHBJ7eFAXfsPqZB1q –  Aug 10 '16 at 12:01

1 Answers1

5

Looks like you can fix it by waiting for the loadeddata event of the video's

Here is the basic idea:

function waitForvidLoad(vids, callback) {
     /* if no videos i.e. mobile mode only gifs and jpgs then call callback else masonry breaks.*/
        if(vids.length === 0){
            callback();
        }
    var vidsLoaded = 0;
    vids.on('loadeddata', function() {
      vidsLoaded++;
      if (vids.length === vidsLoaded) {
        callback();
      }
    });
  }

.

  var $container = $('#container');
  var vids = $('#container').find('video');
  waitForvidLoad(vids, function() {
    $container.imagesLoaded(function() {
      $container.masonry({
        itemSelector: '.box',
        columnWidth: 100
      });
  });

Working plunker here: http://plnkr.co/edit/jXJ7oFxF3sFWBAJuBqdQ?p=preview

Willem D'Haeseleer
  • 17,802
  • 6
  • 58
  • 92
  • how is this working for second page load too ? i dont get it. i mean i dont see anything for $container.infinitescroll –  Aug 11 '16 at 03:54
  • Hmm, probably because the assets are cached, I couldn't test with cache disabled because the video's load really really slow. You can probably apply the same solution to the infinitescroll loading code. – Willem D'Haeseleer Aug 11 '16 at 04:16
  • @AMB Where you able to use this to fix the issue on your website ? – Willem D'Haeseleer Aug 11 '16 at 15:53
  • Hi, not yet, i am still trying various code combinations , but none are working, yet. for initial load its working fine bcoz i used window.load but the issue is for seconds load. –  Aug 11 '16 at 16:20
  • i tried exact same code from plunkr , now there are vertical gaps in masonry, but no more video overlapping. –  Aug 11 '16 at 16:52
  • okie., update, if i use your code even for initial loading, then its breaking masonry, vertical gaps are there. i double checked, if i dont use your solution then masonry works fine, for initial load, any specific reason ? ill add diferrent diamension images in the demo, so it will be clear as to whats breaking the masonry. –  Aug 11 '16 at 17:06
  • okie., here is new plunkr which shows masonry breaks using the same old code. + solution , http://embed.plnkr.co/7Ibw9eCFu0N49HEDWtmv/ –  Aug 11 '16 at 17:16
  • looks like masonry is not being called at all., –  Aug 12 '16 at 06:07
  • @AMB I updated the code with a working plunker, give it a try now. Sorry for the mess up there. – Willem D'Haeseleer Aug 12 '16 at 16:05
  • Hi, np, but the masonry is still not being called, you can see the empty vertical gaps. –  Aug 12 '16 at 16:17
  • @AMB Sorry messed up again, check the plunker again please. It does take some time for masonry to start because the video's load so slow. You could solve that with some sort of overlay and preloading the video's, that's a different issue tough I think. – Willem D'Haeseleer Aug 12 '16 at 16:28
  • Thanks, its working perfect as expected and indeed its kind of slow , but i guess thats problem with server serving videos. ill look into it more., thanks. –  Aug 12 '16 at 16:50
  • update, masonry wan't being called when theres no video element, so i updated waitForvidLoad function , http://plnkr.co/edit/ABvyweIOSET3VWvWV1lm?p=preview –  Aug 12 '16 at 23:26
  • Ah good catch, I updated the answer to include that as well. Hope everything works now ! Please feel free to accept the answer if you have no other issues with the solution :D – Willem D'Haeseleer Aug 12 '16 at 23:31