25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

164 lines
3.7 KiB

  1. // import $ from 'jquery';
  2. const $ = require('jquery');
  3. class Masonry {
  4. constructor(row, buttonText, sizes) {
  5. this.section = row.addClass('initiated');
  6. this.sizes = sizes;
  7. this.items = [];
  8. this.visibleItems = [];
  9. this.batchSize = 0;
  10. this.btn = $('<button class="btn load-more has-icon icon-laden" />').text(buttonText);
  11. row.children().each((i, element) => {
  12. this.items.push($(element).remove());
  13. })
  14. row.after($('<div class="button-wrapper" />').append(this.btn));
  15. this.btn.on('click', (e) => {
  16. e.preventDefault();
  17. this.addBatch();
  18. })
  19. this.buildCols();
  20. this.addBatch();
  21. this.handleResize();
  22. }
  23. addBatch() {
  24. const newItems = [];
  25. for (let i = 0; i < this.batchSize; i++) {
  26. if (this.items.length > 0) {
  27. if (this.items[0].attr('data-thumb')) {
  28. this.loadImage(this.items[0]);
  29. }
  30. this.items[0].find('img[data-src]').each((i, el) => {
  31. $(el).one('load', (e) => {
  32. $(e.currentTarget).addClass('loaded');
  33. }).attr('src', $(el).attr('data-src'))
  34. })
  35. this.visibleItems.push(this.items[0]);
  36. newItems.push(this.items[0].css({'opacity': 0, 'transform': 'scale(0.8)', 'transition': '0.4s ease ' + (0.07 * i) + 's'}));
  37. this.items.splice(0,1);
  38. }
  39. }
  40. if (this.items.length === 0) {
  41. this.btn.parent().hide();
  42. }
  43. this.addToCols(newItems);
  44. }
  45. loadImage(item) {
  46. const img = $('<img src="' + this.items[0].attr('data-thumb') + '" alt="" />').one('load', () => {
  47. setTimeout(() => {
  48. item.addClass('loaded');
  49. },200)
  50. })
  51. item.find('a').append(img);
  52. }
  53. handleResize() {
  54. this.width = this.section.outerWidth();
  55. this.timer = null;
  56. $(window).on('resize', () => {
  57. if (this.timer) {
  58. clearTimeout(this.timer);
  59. }
  60. setTimeout(() => {
  61. this.buildCols();
  62. },200);
  63. })
  64. }
  65. buildCols() {
  66. const w = this.section.width();
  67. let cols = 1;
  68. $.each(this.sizes, (i, size) => {
  69. if (w > size.minWidth) {
  70. cols = i + 1;
  71. this.batchSize = size.batchSize;
  72. }
  73. else {
  74. return false;
  75. }
  76. })
  77. if (this.cols && cols === this.cols.length) {
  78. return;
  79. }
  80. $.each(this.cols, (i, item) => {
  81. item.col.remove();
  82. })
  83. this.cols = [];
  84. this.section.attr('data-cols', cols);
  85. for (let i = 0; i < cols; i++) {
  86. const col = $('<div class="column" />').appendTo(this.section);
  87. this.cols.push({
  88. col: col,
  89. index: i,
  90. height: 0
  91. })
  92. }
  93. this.addToCols(this.visibleItems);
  94. }
  95. addToCols(items) {
  96. $.each(items, (i, element) => {
  97. const item = $(element);
  98. this.cols[0].col.append(item);
  99. this.cols[0].height = Math.round(item.position().top + item.outerHeight());
  100. this.cols.sort( this.compareCols );
  101. window.requestAnimationFrame(() => {
  102. item.css({'opacity': '1', 'transform': 'scale(1)'});
  103. })
  104. })
  105. }
  106. compareCols(a, b) {
  107. if (a.height < b.height) {
  108. return -1;
  109. }
  110. else if (a.height > b.height) {
  111. return 1;
  112. }
  113. else {
  114. if (a.index < b.index) {
  115. return -1;
  116. }
  117. if (a.index > b.index) {
  118. return 1;
  119. }
  120. }
  121. return 0;
  122. }
  123. }
  124. export default Masonry;
  125. $('body').on('ihk-init dynamic-component-loaded gfi-dynamic-init', function () {
  126. $('.teasers[data-type="masonry"] .row:not(.initiated)').each((i, el) => {
  127. const btnText = window.ihk.translations.loadMoreArticles;
  128. const selector = $(el);
  129. if (!selector.find('dynamic-content').length) {
  130. new Masonry(selector, btnText,[
  131. { minWidth: 0, batchSize: 2 },
  132. { minWidth: 567, batchSize: 3 },
  133. { minWidth: 1000, batchSize: 6 }
  134. ]);
  135. }
  136. });
  137. });