grid.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*!
  2. * Setup Isotope Grid
  3. *
  4. * JavaScript specific to posts displayed in a grid templates
  5. *
  6. * Initiates Isotope, handles sorting and triggers lazy-loading for images
  7. *
  8. * @package Altofocus
  9. */
  10. /* global loadedPosts */
  11. ( function( $ ) {
  12. // Define initial variable for Isotope
  13. var $body = $( document.body ),
  14. $isotopeWrap = $( '.hfeed:not(.error404, .search-no-results) #main' ),
  15. isoOptions = {
  16. layoutMode: 'masonry',
  17. itemSelector: '.grid-item',
  18. masonry: {
  19. columnWidth: '.grid-sizer',
  20. gutter: '.gutter-sizer'
  21. },
  22. percentPosition: true
  23. };
  24. /**
  25. * Debounce script
  26. */
  27. function altofocus_debounce(func, wait, immediate) {
  28. var timeout;
  29. return function() {
  30. var context = this,
  31. args = arguments;
  32. var later = function() {
  33. timeout = null;
  34. if (!immediate) {
  35. func.apply(context, args);
  36. }
  37. };
  38. var callNow = immediate && !timeout;
  39. clearTimeout(timeout);
  40. timeout = setTimeout(later, wait);
  41. if (callNow) {
  42. func.apply(context, args);
  43. }
  44. };
  45. }
  46. /**
  47. * Init Isotope
  48. *
  49. * - Add Isotope class
  50. * - Add empty grid sizing elements for resposnive isotope sizing
  51. */
  52. function initIsotope() {
  53. // Init Isotope
  54. $isotopeWrap
  55. .append( "<div class=\'grid-sizer\'></div><div class=\'gutter-sizer\'></div>" );
  56. }
  57. /**
  58. * Run Isotope
  59. */
  60. function runIsotope() {
  61. $isotopeWrap.imagesLoaded().fail( function() {
  62. // broken images
  63. // console.log('All images loaded but at least one is broken');
  64. // Initialize Isotope
  65. $isotopeWrap.isotope( isoOptions );
  66. } ).done( function() {
  67. // Initialize Isotope
  68. $isotopeWrap.isotope( isoOptions );
  69. } );
  70. // jQuery
  71. $isotopeWrap.on( 'layoutComplete', function() {
  72. $isotopeWrap.addClass( "has-isotope" );
  73. } );
  74. }
  75. /**
  76. * Triggers re-layout on Isotope wrapper after infinite scroll has loaded new posts
  77. */
  78. function reLayoutIsotope( loadedPosts ) {
  79. // Set array for newly added post IDs
  80. var newPostIds = [];
  81. // If new posts have been loaded from Infinite Scroll, attach them to the isotope wrapper and lay them out
  82. // note: loadedPosts variable is set globally in altofocus_infinite_scroll_render(). See jetpack.php
  83. if ( typeof loadedPosts !== 'undefined' ) {
  84. // Create post IDs from IS results and push into post ID array
  85. $.each( JSON.parse(loadedPosts), function( index, value ) {
  86. var $appendedPost = '#post-'+ value;
  87. newPostIds.push( $appendedPost );
  88. });
  89. // Place infinite scroll results into a jQuery object
  90. var $newPostObj = $( newPostIds.join( ", " ) ),
  91. $appendedPosts = $( $newPostObj );
  92. // Get each new post, add it to Isotope, and relayout Isotope
  93. $appendedPosts
  94. // Hide newly loaded posts to prevent animation jumping
  95. .hide()
  96. // Get each post with an image and without
  97. .each( function() {
  98. var $this = $( this );
  99. // Cue posts with images separately to account for varying image load times
  100. if ( $this.find( "img" ).length > 0 ) {
  101. // Make sure images are loaded before laying them out
  102. $this.imagesLoaded()
  103. // After image load completes, append newly loaded posts to Isotope wrapper and lay them out
  104. .done( altofocus_debounce( function() {
  105. $isotopeWrap
  106. // Append this post
  107. .append( $this )
  108. // Layout this post
  109. .isotope( 'appended', $this );
  110. }, 200, 1 ) );
  111. // Append and layout posts without images normally
  112. } else {
  113. $isotopeWrap
  114. // Append this post
  115. .append( $this )
  116. // Layout this post
  117. .isotope( 'appended', $this );
  118. }
  119. });
  120. }
  121. }
  122. /**
  123. * Document calls
  124. */
  125. $( document )
  126. .ready( initIsotope )
  127. .ready( function() {
  128. /**
  129. * Relayout Isotope on post-load (Infinite Scroll)
  130. */
  131. $body.on( 'post-load', function() {
  132. var loadedPosts = $('#infinite-ids').attr('data');
  133. reLayoutIsotope( loadedPosts );
  134. $('#infinite-ids').remove();
  135. });
  136. /**
  137. * Window calls
  138. */
  139. $( window )
  140. .load( runIsotope );
  141. } );
  142. } )( jQuery );