Friday, December 1, 2017

Javascript looping over items and swapping out items into HTML

Leave a Comment

I'm using the following code i found from CodePen ... Im terrible at JS and I was hoping someone could help me out.

  1. How do I make it so the items don't repeat, at the moment, they scroll forever with 20 to a 'page' before the infinite scroll kicks in, what i would like is if there is 50 images in the array, then display those images, 20 to a page and then stop.
  2. I want to put the JS in a seperate file and then use PHP to loop over some results and output the images, is it possible to somehow move the div that is rendering the images out of the javascript function? so that i can put them in actually in the block in the html?

This is the code i have in the HTML portion

<div id="SlideMiddle">     <div id="grid">         <div id="grid-content"></div>     </div> </div> 

and this is the javascript

<script>     var Imgs = [         'https://tympanus.net/Development/GridLoadingEffects/images/1.jpg',         'https://tympanus.net/Development/GridLoadingEffects/images/3.jpg',         'https://d13yacurqjgara.cloudfront.net/users/64706/screenshots/1167254/attachments/152315/SUGARSKULL-01.png',         'https://tympanus.net/Development/GridLoadingEffects/images/8.jpg',         'https://tympanus.net/Development/GridLoadingEffects/images/10.png',         'https://tympanus.net/Development/GridLoadingEffects/images/14.png',         'https://tympanus.net/Development/GridLoadingEffects/images/9.jpg',         'https://tympanus.net/Development/GridLoadingEffects/images/13.png',         'https://tympanus.net/Development/GridLoadingEffects/images/12.png',         'https://tympanus.net/Development/GridLoadingEffects/images/4.jpg',         'http://www.thedrum.com/uploads/news/172673/DzrMPF_DeezerPoster_MusicSoundBetterWithYou_03.jpg'     ];      $(document).ready(function(){         $grid = $('#grid-content');          $.fn.revealItems = function($items){              var iso = this.data('isotope');             var itemSelector = iso.options.itemSelector;             $items.hide();             $(this).append($items);             $items.imagesLoaded().progress(function(imgLoad, image){                 var $item = $(image.img).parents(itemSelector);                 $item.show();                 iso.appended($item);             });              return this;         }         $grid.isotope({             containerStyle: null,             masonry:{                 columnWidth: 300,                 gutter: 15             },             itemSelector: '.grid-item',             filter : '*',             transitionDuration: '0.4s'         });           $grid.imagesLoaded().progress(function(){             $grid.isotope();         })          function GenerateItems(){             var items = '';             for(var i=0; i < 20; i++){                 items += '<div class="grid-item c'+(i%9)+' wow fadeInUp" ><a href=""><img src="'+Imgs[i%Imgs.length]+'" /></a></div>';             }             return $(items);         }          // SimpleInfiniteScroll         function Infinite(e){             if((e.type == 'scroll') || e.type == 'click'){                 var doc = document.documentElement;                 var top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);                 var bottom = top + $(window).height();                 var docBottom = $(document).height();                  if(bottom + 50 >= docBottom){                     $grid.revealItems(GenerateItems());                 }             }         }          $grid.revealItems(GenerateItems());          $(window).resize(function(){             var margin=40;             var padding=15;             var columns=0;             var cWidth=300;             var windowWidth = $(window).width();              var overflow = false;             while(!overflow){                 columns++;                 var WidthTheory = ((cWidth*columns)+((columns+1)*padding)+margin);                 if(WidthTheory > windowWidth)                     overflow = true;             }             if(columns > 1)                 columns--;              var GridWidth = ((cWidth*columns)+((columns+1)*padding)+margin);              if( GridWidth != $('#grid').width()){                 $('#grid').width(GridWidth);             }         });         $(window).scroll(Infinite);         new WOW().init();      }) </script> 

4 Answers

Answers 1

Images Repeating

There are two things contributing to the image repeating behavior. First, as pointed out in another answer, the loop counter is hard coded to 20. So if you pass in five images, each will repeat four times. Changing 20 to the length of the Imgs array will prevent this.

Second, the GenerateItems() function always returns results.

if there is 50 images in the array, then display those images, 20 to a page and then stop

This implies that GenerateItems() will need to return an empty set (or not be called) after all 50 images have been displayed. A naive approach might involve a global page counting variable. In this codepen, I added such a variable to limit the number of pages, like so:

var pagesServed = 0;  $(document).ready(function(){      $grid = $('#grid-content'); ..... function GenerateItems(){     console.log("generating items");     var items = '';     if (++pagesServed > 2) {        return items;      }     for(var i=0; i < Imgs.length; i++){       .... 

Server side rendering

In a real life use case, you're probably fetching this list of image links from your server, which ties into the second part of your question.

You can easily render these divs on the server side instead. The GenerateItems() function would make an AJAX call to your back end to get the divs, rather than building them in javascript. That PHP code might look something like this:

<?php require_once __DIR__.'/vendor/autoload.php';  session_start();  $Imgs = [     'https://tympanus.net/Development/GridLoadingEffects/images/1.jpg',     'https://tympanus.net/Development/GridLoadingEffects/images/3.jpg',     'https://d13yacurqjgara.cloudfront.net/users/64706/screenshots/1167254/attachments/152315/SUGARSKULL-01.png',     'https://tympanus.net/Development/GridLoadingEffects/images/8.jpg',     'https://tympanus.net/Development/GridLoadingEffects/images/10.png',     'https://tympanus.net/Development/GridLoadingEffects/images/14.png',     'https://tympanus.net/Development/GridLoadingEffects/images/9.jpg',     'https://tympanus.net/Development/GridLoadingEffects/images/13.png',     'https://tympanus.net/Development/GridLoadingEffects/images/12.png',     'https://tympanus.net/Development/GridLoadingEffects/images/4.jpg',     'http://www.thedrum.com/uploads/news/172673/DzrMPF_DeezerPoster_MusicSoundBetterWithYou_03.jpg' ];  $items = '';  for ($i=0; $i < 20; $i++){     $items .= '<div class="grid-item c' . ($i % 9) . ' wow fadeInUp" ><a href=""><img src="' . $Imgs[$i % count($Imgs)] . '" /></a></div>'; } header('Access-Control-Allow-Origin: *'); printf($items); 

Then GenerateItems() would look roughly like this:

  function GenerateItems(){       console.log("generating items");       var fetched =  fetch('http://localhost:8000').then(function(data) {           return data.text();       });        return fetched;     } 

And revealItems is modified to deal with the Promise:

$.fn.revealItems = function($items){     var self = this;     var iso = this.data('isotope');     var itemSelector = iso.options.itemSelector;     $items.then(function($fetcheditems) {         console.log($fetcheditems);         $($fetcheditems).hide();         $(self).append($fetcheditems);         $($fetcheditems).imagesLoaded().progress(function(imgLoad, image){             var $item = $(image.img).parents(itemSelector);             $item.show();             iso.appended($item);         });     });     return this; } 

I put an example that renders these divs on the server side on GitHub. Disclaimer - It's a minimal example - I didn't bother getting the WOW styling to work, and the CORS support is minimal (e.g. no Access-Control-Allow-Credentials header is set).

You'd need to implement your own server side logic to decide which images to return on each call. For example, you could use session to keep track of which ones have already been served, or you could accept query string parameters that define the range of images being requested.

Answers 2

  1. For the first question I would change GenerateItems procedure

    function GenerateItems(){     var items = '';     var limit = Imgs.length > 20 ? 20 : Imgs.length;     for(var i=0; i < limit; i++){         items += '<div class="grid-item c'+(i%9)+' wow fadeInUp" ><a href=""><img src="'+Imgs[i%Imgs.length]+'" /></a></div>';     }     return $(items); } 

But can you provide plunter or Codepen with example with styling plz?

  1. If I understand correctly you need to feed selector there you want images to be generated?

a) Then just defined function from JS file:

function infiniteList(selector){     $grid = $(selector); 

..... }

b) attach JS file in index.html header

c) call function with needed selector in $(document).ready in index.html script section (put it before closing tag).

var selector = ...//some calculation to get selector $(document).ready(infiniteList(selector)); 

Answers 3

For the first question I think you just want to get rid of infinite scroll. Check here- https://codepen.io/anon/pen/mqawpy Simply comment line no. 117 of your pen.

//$(window).scroll(Infinite); 

And for second, you can use tag to insert the HTML content i.e. "..." tag of HTML using PHP. check here- How to write html code inside <?php ?>

Answers 4

i would suggest scrollmagic plugin for this

ifinite scroll

hope source code will solve your solution.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment