og-grid multiple grid fix


/ Published in: JavaScript
Save to your folder(s)

wp-content/themes/halfcreative/js/grid.js - replace the contents with the provided code.
Or "whatever your themepath is"/js/grid.js


Copy this code and paste it in your HTML
  1. /*
  2.  * throttledresize: special jQuery event that happens at a reduced rate compared to "resize"
  3.  *
  4.  * latest version and complete README available on Github:
  5.  * https://github.com/louisremi/jquery-smartresize
  6.  *
  7.  * Copyright 2012 @louis_remi
  8.  * Licensed under the MIT license.
  9.  *
  10.  * This saved you an hour of work?
  11.  * Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON
  12.  */
  13. (function($) {
  14.  
  15. var $event = $.event,
  16. $special,
  17. dummy = {_: 0},
  18. frame = 0,
  19. wasResized, animRunning;
  20.  
  21. $special = $event.special.throttledresize = {
  22. setup: function() {
  23. $(this).on("resize", $special.handler);
  24. },
  25. teardown: function() {
  26. $(this).off("resize", $special.handler);
  27. },
  28. handler: function(event, execAsap) {
  29. // Save the context
  30. var context = this,
  31. args = arguments;
  32.  
  33. wasResized = true;
  34.  
  35. if (!animRunning) {
  36. setInterval(function() {
  37. frame++;
  38.  
  39. if (frame > $special.threshold && wasResized || execAsap) {
  40. // set correct event type
  41. event.type = "throttledresize";
  42. $event.dispatch.apply(context, args);
  43. wasResized = false;
  44. frame = 0;
  45. }
  46. if (frame > 9) {
  47. $(dummy).stop();
  48. animRunning = false;
  49. frame = 0;
  50. }
  51. }, 30);
  52. animRunning = true;
  53. }
  54. },
  55. threshold: 0
  56. };
  57.  
  58. })(jQuery);
  59.  
  60. /* ======================= imagesLoaded Plugin ===============================
  61.  https://github.com/desandro/imagesloaded
  62.  
  63.  $('#my-container').imagesLoaded(myFunction)
  64.  execute a callback when all images have loaded.
  65.  needed because .load() doesn't work on cached images
  66.  
  67.  callback function gets image collection as argument
  68.  this is the container
  69.  
  70.  original: MIT license. Paul Irish. 2010.
  71.  contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou
  72.  
  73.  blank image data-uri bypasses webkit log warning (thx doug jones)
  74.  */
  75. $ = jQuery;
  76. var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
  77.  
  78. $.fn.imagesLoaded = function(callback) {
  79. var $this = this,
  80. deferred = $.isFunction($.Deferred) ? $.Deferred() : 0,
  81. hasNotify = $.isFunction(deferred.notify),
  82. $images = $this.find('img').add($this.filter('img')),
  83. loaded = [],
  84. proper = [],
  85. broken = [];
  86.  
  87. // Register deferred callbacks
  88. if ($.isPlainObject(callback)) {
  89. $.each(callback, function(key, value) {
  90. if (key === 'callback') {
  91. callback = value;
  92. } else if (deferred) {
  93. deferred[key](value);
  94. }
  95. });
  96. }
  97.  
  98. function doneLoading() {
  99. var $proper = $(proper),
  100. $broken = $(broken);
  101.  
  102. if (deferred) {
  103. if (broken.length) {
  104. deferred.reject($images, $proper, $broken);
  105. } else {
  106. deferred.resolve($images);
  107. }
  108. }
  109.  
  110. if ($.isFunction(callback)) {
  111. callback.call($this, $images, $proper, $broken);
  112. }
  113. }
  114.  
  115. function imgLoaded(img, isBroken) {
  116. // don't proceed if BLANK image, or image is already loaded
  117. if (img.src === BLANK || $.inArray(img, loaded) !== -1) {
  118. return;
  119. }
  120.  
  121. // store element in loaded images array
  122. loaded.push(img);
  123.  
  124. // keep track of broken and properly loaded images
  125. if (isBroken) {
  126. broken.push(img);
  127. } else {
  128. proper.push(img);
  129. }
  130.  
  131. // cache image and its state for future calls
  132. $.data(img, 'imagesLoaded', {isBroken: isBroken, src: img.src});
  133.  
  134. // trigger deferred progress method if present
  135. if (hasNotify) {
  136. deferred.notifyWith($(img), [isBroken, $images, $(proper), $(broken)]);
  137. }
  138.  
  139. // call doneLoading and clean listeners if all images are loaded
  140. if ($images.length === loaded.length) {
  141. setTimeout(doneLoading);
  142. $images.unbind('.imagesLoaded');
  143. }
  144. }
  145.  
  146. // if no images, trigger immediately
  147. if (!$images.length) {
  148. doneLoading();
  149. } else {
  150. $images.bind('load.imagesLoaded error.imagesLoaded', function(event) {
  151. // trigger imgLoaded
  152. imgLoaded(event.target, event.type === 'error');
  153. }).each(function(i, el) {
  154. var src = el.src;
  155.  
  156. // find out if this image has been already checked for status
  157. // if it was, and src has not changed, call imgLoaded on it
  158. var cached = $.data(el, 'imagesLoaded');
  159. if (cached && cached.src === src) {
  160. imgLoaded(el, cached.isBroken);
  161. return;
  162. }
  163.  
  164. // if complete is true and browser supports natural sizes, try
  165. // to check for image status manually
  166. if (el.complete && el.naturalWidth !== undefined) {
  167. imgLoaded(el, el.naturalWidth === 0 || el.naturalHeight === 0);
  168. return;
  169. }
  170.  
  171. // cached images don't fire load sometimes, so we reset src, but only when
  172. // dealing with IE, or image is complete (loaded) and failed manual check
  173. // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
  174. if (el.readyState || el.complete) {
  175. el.src = BLANK;
  176. el.src = src;
  177. }
  178. });
  179. }
  180.  
  181. return deferred ? deferred.promise($this) : $this;
  182. };
  183.  
  184. var Grid = (function() {
  185.  
  186. // list of items
  187. var $grid = $('.og-grid'),
  188. // the items
  189. $items = $grid.children('li'),
  190. // current expanded item's index
  191. current = -1,
  192. // position (top) of the expanded item
  193. // used to know if the preview will expand in a different row
  194. previewPos = -1,
  195. // extra amount of pixels to scroll the window
  196. scrollExtra = 0,
  197. // extra margin when expanded (between preview overlay and the next items)
  198. marginExpanded = 10,
  199. $window = $(window), winsize,
  200. $body = $('html, body'),
  201. // transitionend events
  202. transEndEventNames = {
  203. 'WebkitTransition': 'webkitTransitionEnd',
  204. 'MozTransition': 'transitionend',
  205. 'OTransition': 'oTransitionEnd',
  206. 'msTransition': 'MSTransitionEnd',
  207. 'transition': 'transitionend'
  208. },
  209. transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ],
  210. // support for csstransitions
  211. support = Modernizr.csstransitions,
  212. // default settings
  213. settings = {
  214. minHeight: 460,
  215. speed: 350,
  216. easing: 'ease'
  217. };
  218.  
  219. function init(config) {
  220.  
  221. $grid = $('.og-grid');
  222. settings.minHeight = $grid.attr("data-minheight") ? parseInt($grid.attr("data-minheight"), 10) : settings.minHeight;
  223. // the items
  224. $items = $grid.children('li');
  225.  
  226. settings = $.extend(true, {}, settings, config);
  227.  
  228. // preload all images
  229. $grid.imagesLoaded(function() {
  230.  
  231. // save item´s size and offset
  232. saveItemInfo(true);
  233. // get window´s size
  234. getWinSize();
  235. // initialize some events
  236. initEvents();
  237.  
  238. });
  239.  
  240. }
  241.  
  242. // saves the item´s offset top and height (if saveheight is true)
  243. function saveItemInfo(saveheight) {
  244. $items.each(function() {
  245. var $item = $(this);
  246. $item.data('offsetTop', $item.offset().top);
  247. if (saveheight) {
  248. $item.data('height', $item.height());
  249. }
  250. });
  251. }
  252.  
  253. function initEvents() {
  254.  
  255. // when clicking an item, show the preview with the item´s info and large image.
  256. // close the item if already expanded.
  257. // also close if clicking on the item´s cross
  258. $items.on('click', 'span.og-close', function() {
  259. hidePreview();
  260. return false;
  261. }).children('a').on('click', function(e) {
  262.  
  263. var $item = $(this).parent();
  264. // check if item already opened
  265.  
  266. current === $items.index($item) ? hidePreview() : showPreview($item);
  267. return false;
  268.  
  269. });
  270.  
  271. // on window resize get the window´s size again
  272. // reset some values..
  273. $window.on('debouncedresize', function() {
  274.  
  275. scrollExtra = 0;
  276. previewPos = -1;
  277. // save item´s offset
  278. saveItemInfo();
  279. getWinSize();
  280. var preview = $.data(this, 'preview');
  281. if (typeof preview != 'undefined') {
  282. hidePreview();
  283. }
  284.  
  285. });
  286.  
  287. }
  288.  
  289. function getWinSize() {
  290. winsize = {width: $window.width(), height: $window.height()};
  291. }
  292.  
  293. function showPreview($item) {
  294.  
  295. var preview = $.data(this, 'preview'),
  296. // item´s offset top
  297. position = $item.data('offsetTop');
  298.  
  299. scrollExtra = 0;
  300.  
  301. // if a preview exists and previewPos is different (different row) from item´s top then close it
  302. if (typeof preview != 'undefined') {
  303.  
  304. // not in the same row
  305. if (previewPos !== position) {
  306. // if position > previewPos then we need to take te current preview´s height in consideration when scrolling the window
  307. if (position > previewPos) {
  308. scrollExtra = preview.height;
  309. }
  310. hidePreview();
  311. }
  312. // same row
  313. else {
  314. preview.update($item);
  315. return false;
  316. }
  317.  
  318. }
  319.  
  320. // update previewPos
  321. previewPos = position;
  322. // initialize new preview for the clicked item
  323. preview = $.data(this, 'preview', new Preview($item));
  324. // expand preview overlay
  325. preview.open();
  326.  
  327. }
  328.  
  329. function hidePreview() {
  330. current = -1;
  331. var preview = $.data(this, 'preview');
  332. preview.close();
  333. $.removeData(this, 'preview');
  334. }
  335.  
  336. // the preview obj / overlay
  337. function Preview($item) {
  338. this.$item = $item;
  339. this.expandedIdx = $items.index($item);
  340. this.create();
  341. this.update();
  342. }
  343.  
  344. Preview.prototype = {
  345. create: function() {
  346. // create Preview structure:
  347. this.$title = $('<h3></h3>');
  348. this.$description = $('<p></p>');
  349. this.$href = $('<div><a href="#">Visit website</a></div>');
  350. this.$details = $('<div class="og-details"></div>').append(this.$title, this.$description, this.$href);
  351. this.$loading = $('<div class="og-loading"></div>');
  352. this.$fullimage = $('<div class="og-fullimg"></div>').append(this.$loading);
  353. this.$closePreview = $('<span class="og-close"></span>');
  354. this.$previewInner = $('<div class="og-expander-inner"></div>').append(this.$closePreview, this.$fullimage, this.$details);
  355. this.$previewEl = $('<div class="og-expander"></div>').append(this.$previewInner);
  356. // append preview element to the item
  357. this.$item.append(this.getEl());
  358. // set the transitions for the preview and the item
  359. if (support) {
  360. this.setTransition();
  361. }
  362. },
  363. update: function($item) {
  364. if ($item) {
  365. this.$item = $item;
  366. }
  367.  
  368. // if already expanded remove class "og-expanded" from current item and add it to new item
  369. if (current !== -1) {
  370. var $currentItem = $items.eq(current);
  371. $currentItem.removeClass('og-expanded');
  372. this.$item.addClass('og-expanded');
  373. // position the preview correctly
  374. this.positionPreview();
  375. }
  376.  
  377. // update current value
  378. current = $items.index(this.$item);
  379.  
  380. // update preview´s content
  381. var $itemEl = this.$item.children('a'),
  382. eldata = {
  383. href: $itemEl.attr('href'),
  384. largesrc: $itemEl.data('largesrc'),
  385. title: $itemEl.data('title'),
  386. link: $itemEl.attr('data-link-url'),
  387. label: $itemEl.attr('data-link-label'),
  388. description: $itemEl.data('description')
  389. };
  390.  
  391. this.$title.html(eldata.title);
  392. this.$description.html(eldata.description);
  393. if (eldata.label) {
  394. this.$href.html('<a href="' + eldata.link + '">' + eldata.label + '</a>').show();
  395. } else {
  396. this.$href.hide();
  397. }
  398. //this.$href.attr( 'href', eldata.href );
  399.  
  400.  
  401. var self = this;
  402.  
  403. // remove the current image in the preview
  404. if (typeof self.$largeImg != 'undefined') {
  405. self.$largeImg.remove();
  406. }
  407.  
  408. // preload large image and add it to the preview
  409. // for smaller screens we don´t display the large image (the media query will hide the fullimage wrapper)
  410. if (self.$fullimage.is(':visible')) {
  411. this.$loading.show();
  412. $('<img/>').load(function() {
  413. var $img = $(this);
  414. if ($img.attr('src') === self.$item.children('a').data('largesrc')) {
  415. self.$loading.hide();
  416. self.$fullimage.find('img').remove();
  417. self.$largeImg = $img.fadeIn(350);
  418. if ($.browser.msie) {
  419. self.$largeImg.width("auto").height("auto");
  420. }
  421. self.$fullimage.append(self.$largeImg);
  422. }
  423. }).attr('src', eldata.largesrc);
  424. }
  425.  
  426. },
  427. open: function() {
  428.  
  429. setTimeout($.proxy(function() {
  430. // set the height for the preview and the item
  431. this.setHeights();
  432. // scroll to position the preview in the right place
  433. this.positionPreview();
  434. }, this), 25);
  435.  
  436. },
  437. close: function() {
  438. var self = this,
  439. onEndFn = function() {
  440. if (support) {
  441. $(this).off(transEndEventName);
  442. }
  443. self.$item.removeClass('og-expanded');
  444. self.$previewEl.remove();
  445. };
  446.  
  447. setTimeout($.proxy(function() {
  448.  
  449. if (typeof this.$largeImg !== 'undefined') {
  450. this.$largeImg.fadeOut('fast');
  451. }
  452. this.$previewEl.css('height', 0);
  453. // the current expanded item (might be different from this.$item)
  454. var $expandedItem = $items.eq(this.expandedIdx);
  455. console.log($expandedItem);
  456. $expandedItem.css('height', $expandedItem.data('height')).on(transEndEventName, onEndFn);
  457.  
  458. if (!support) {
  459. onEndFn.call();
  460. }
  461.  
  462. }, this), 25);
  463.  
  464. return false;
  465.  
  466. },
  467. calcHeight: function() {
  468.  
  469. var heightPreview = winsize.height - this.$item.data('height') - marginExpanded,
  470. itemHeight = winsize.height;
  471.  
  472. if (heightPreview < settings.minHeight) {
  473. heightPreview = settings.minHeight;
  474. itemHeight = settings.minHeight + this.$item.data('height') + marginExpanded;
  475. }
  476.  
  477. this.height = heightPreview;
  478. this.itemHeight = itemHeight;
  479.  
  480. },
  481. setHeights: function() {
  482.  
  483. var self = this,
  484. onEndFn = function() {
  485. if (support) {
  486. self.$item.off(transEndEventName);
  487. }
  488. self.$item.addClass('og-expanded');
  489. };
  490.  
  491. this.calcHeight();
  492. this.$previewEl.css('height', this.height);
  493. //this.itemHeight = "auto";
  494. this.$item.css('height', this.itemHeight).on(transEndEventName, onEndFn);
  495.  
  496. if (!support) {
  497. onEndFn.call();
  498. }
  499.  
  500. },
  501. positionPreview: function() {
  502.  
  503. // scroll page
  504. // case 1 : preview height + item height fits in window´s height
  505. // case 2 : preview height + item height does not fit in window´s height and preview height is smaller than window´s height
  506. // case 3 : preview height + item height does not fit in window´s height and preview height is bigger than window´s height
  507. var position = this.$item.data('offsetTop'),
  508. previewOffsetT = this.$previewEl.offset().top - scrollExtra,
  509. scrollVal = this.height + this.$item.data('height') + marginExpanded <= winsize.height ? position : this.height < winsize.height ? previewOffsetT - (winsize.height - this.height) : previewOffsetT;
  510.  
  511. $body.animate({scrollTop: scrollVal}, settings.speed);
  512.  
  513. },
  514. setTransition: function() {
  515. this.$previewEl.css('transition', 'height ' + settings.speed + 'ms ' + settings.easing);
  516. this.$item.css('transition', 'height ' + settings.speed + 'ms ' + settings.easing);
  517. },
  518. getEl: function() {
  519. return this.$previewEl;
  520. }
  521. }
  522.  
  523. return {init: init};
  524.  
  525. })(jQuery);

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.