JQuery: "load more" masonry items?

I have several elements on my page that I load 5 at a time.

What I need to do is animate the loaded elements using animate.css.

To explain this, I created this script:

https://jsfiddle.net/89v781rL/6/

Scroll down to see the Show More button and click on it to see it in action.

When I load more elements, the elements are animated, but because they are laid out in the Masonry style , their position changes, and this is not what I want. Basically I need to keep the elements in their first position and continue to add / load more elements.

If you comment out the following CSS code and run JSFIDDLE, you will see how nicely laid out the elements are, and that is how I want them to be when they load 5 at a time:

 #grid li:nth-child(n+6) { /*display: none;*/ } 

what I need to do is bounce UP elements using animate.css.

This is my complete code:

 $('#sales').click(function() { $('#grid li').not(':visible').slice(0, 5).slideDown(); $('#grid li').not(':visible').slice(0, 5).addClass('animated bounceInUp'); }); 

Note: I do not want to use any plugins like this

Mostly because it is very large and bloated for my project, and it also does not work properly in my project.

Can anyone consult on this issue?

EDIT:

Here is another unsuccessful attempt to do this:

https://jsfiddle.net/89v781rL/8/

And this too:

https://jsfiddle.net/89v781rL/9/

+5
source share
2 answers

TL DR: Proposed solution .


Simply put, what you want is impossible. At least not how you started it.

But here's the thing: the reason I got into the encoding (based on the background design, as well as the main reason I answered your question) is because a bunch of web developers told me about the specific project that I did possible. So I (repeatedly) searched and experimented until I found a way.

Since then, when I came to this conclusion, I always translated it into:
Maybe I'm just doing it wrong β„’ .


In your particular case, you use the β€œbrickwork” technique, which is not exactly brickwork. This is a column layout method called CSS columns . Here's what he does, from a technical point of view:

  • calculates the width of the columns, taking into account the parent total width, the number of columns and the column of drains
  • calculates the total height of the content, given the total column width
  • breaks the content into pieces, placing in columns, trying to distribute the content equally, observing any break-inside ads. Note the suggestive name of the property value: avoid , it is not forbid or disallow . Based on the content, this rule is not always applied.

But, in short, this is what your 2-column layout looks like:

 1 4 2 5 3 6 

When you decide to add more content, it will repeat the above steps, given the updated height of the content, resulting in:

 1 5 2 6 3 7 4 

It will calculate the possible fault parameters and go to the one that leads to the lowest height for the parent element. If two or more results are of the same height, most browsers choose the one that makes the later / last column shorter.


If your content should remain in place after processing, the CSS columns method is clearly not an option. So you are looking at methods using absolute positioning. You have many options, but noticeable (I'm probably subjective, but is someone really objective?):

  • Masonry . It comes with a very convenient stamp method specifically designed for your requirement (link existing elements to a place, so adding more content will not be repeated - the position of existing elements - which can happen sometimes, depending on the content and the parent - for example, if you have there is a list of existing short items, and you add a very high one, this will cause the column to be much higher than the rest; have not been called onto existing elements, they will be reassigned so To the resulting columns had minimal difference in height).
  • Isotope - I never had the opportunity to use it, but I heard good things about it.
  • The so-called layout pinterest script . It was written by Evan Sharp , it relies entirely on javascript and absolute positioning (just like Freemasonry), but is incredibly effective. He explains how he did in this SO answer , and here is a good tutorial in technology. If you do not care about the technical part, and they are only interested in juice, I found a light plug-in called Bootstrap Waterfall , which, in addition to everything connected above, has a ready-made version for production.

All I have written so far is that it would take you a little time and decent search fu.

The only step to the left (and the real answer) is to animate each element in the view using the desired animate.css effect. I chose Bootstrap-waterfall for the layout, but you could also go with any other option. Here he is:

 // Included waterfall script as it doesn't load from github for everyone +function(t){"use strict";function i(i){this.$pins=i,this.tasks=[],this.timerId=null,this.deferred=new t.Deferred}function e(t){this.img=t,this.initialWidth=t.width,this.initialHeight=t.height}function n(i){return this.each(function(){var e=t(this),n=e.data("mystist.waterfall"),s="object"==typeof i&&i;n&&"string"!=typeof i&&n.destroy()&&(n=null),n||e.data("mystist.waterfall",n=new o(this,s)),"string"==typeof i&&n[i]()})}var s=s||{now:Date.now||function(){return(new Date).getTime()},throttle:function(t,i,e){var n,o,r,a=null,h=0;e||(e={});var l=function(){h=e.leading===!1?0:s.now(),a=null,r=t.apply(n,o),a||(n=o=null)};return function(){var u=s.now();h||e.leading!==!1||(h=u);var c=i-(uh);return n=this,o=arguments,0>=c||c>i?(a&&(clearTimeout(a),a=null),h=u,r=t.apply(n,o),a||(n=o=null)):a||e.trailing===!1||(a=setTimeout(l,c)),r}},debounce:function(t,i,e){var n,o,r,a,h,l=function(){var u=s.now()-a;i>u&&u>=0?n=setTimeout(l,iu):(n=null,e||(h=t.apply(r,o),n||(r=o=null)))};return function(){r=this,o=arguments,a=s.now();var u=e&&!n;return n||(n=setTimeout(l,i)),u&&(h=t.apply(r,o),r=o=null),h}}},o=function(i,e){this.$element=t(i),this.options=t.extend({},o.DEFAULTS,e),this.id=Math.random().toString().slice(2),this.$fakePin=null,this.$container=null,this.$pins=null,this.pinWidth=null,this.imgWidth=null,this.lefts=[],this.tops=[],this.init().calculateWidth().calculatePosition().sail(),t(window).on("resize.mystist.waterfall"+this.id,s.debounce(t.proxy(function(){t(window).off("scroll.mystist.waterfall"+this.id),this.calculateWidth().calculatePosition().ship(r.getLoadedPins.call(this))},this),777))};o.VERSION="0.2.4",o.DEFAULTS={},o.prototype.init=function(){return this.initPins().initAttributes(),this},o.prototype.initPins=function(){var i=this.$element.children().length>0?this.$element.children().remove():t(this.$element.data("bootstrap-waterfall-template"));return i.each(function(){var i=t(this).find("img:eq(0)");i.length>0&&(t(this).data("bootstrap-waterfall-src",i.attr("src")),i.attr("src","data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="))}),this.$pins=i,this},o.prototype.initAttributes=function(){return this.$fakePin=this.$pins.first().clone(),this.$container=t("<div />").css("position","relative"),this.$element.html(this.$container),this},o.prototype.calculateWidth=function(){var t=this.$fakePin.clone();return this.$container.append(t.css("opacity",0)),this.pinWidth=t.outerWidth(!0),this.imgWidth=t.find("img:eq(0)").css("width","100%").width(),t.remove(),this},o.prototype.calculatePosition=function(){for(var t=parseInt(this.$container.width()/this.pinWidth,10),i=[],e=[],n=0;t>n;n++)i.push(n*this.pinWidth),e.push(0);return this.lefts=i,this.tops=e,this},o.prototype.sail=function(){var e=r.getToLoadPins.call(this),n=new i(e);return n.load().run().deferred.done(t.proxy(function(){this.ship(e)},this)),this},o.prototype.ship=function(i){return this.render(i).updateHeight(),t(window).on("scroll.mystist.waterfall"+this.id,s.throttle(t.proxy(function(){r.isWantMore.call(this)&&(t(window).off("scroll.mystist.waterfall"+this.id),this.sail())},this),500)),this},o.prototype.render=function(i){var e=this;return i.each(function(){e.placePin(t(this))}),this},o.prototype.placePin=function(t){var i=a.indexOf(this.tops,Math.min.apply(null,this.tops)),e=r.getPosition.call(this,i);return t.css({position:"absolute",left:e.left,top:e.top}),t.data("bootstrap-waterfall-pin")&&r.setImageHeight.call(this,t),t.data("bootstrap-waterfall-src")&&(r.makeImageAvailable.call(this,t),t.removeData("bootstrap-waterfall-src")),this.$container.append(t),r.updatePosition.call(this,i,t),this},o.prototype.updateHeight=function(){var t=a.indexOf(this.tops,Math.max.apply(null,this.tops));return this.$container.height(this.tops[t]),this},o.prototype.destroy=function(){return t(window).off("scroll.mystist.waterfall"+this.id),t(window).off("resize.mystist.waterfall"+this.id),this.$element.empty().removeData("mystist.waterfall"),this};var r={getToLoadPins:function(){var i=parseInt(this.$container.width()/this.pinWidth,10),e=3*i,n=this.$pins.map(function(){return t(this).find("img").length>0&&t(this).data("bootstrap-waterfall-src")?t(this):void 0});return n.slice(0,e)},getLoadedPins:function(){var i=this.$pins.map(function(){return t(this).find("img").length>0&&!t(this).data("bootstrap-waterfall-src")?t(this):void 0});return i},isWantMore:function(){return t(window).scrollTop()+t(window).height()>a.getDocHeight()-377?!0:!1},getPosition:function(t){var i={left:this.lefts[t],top:this.tops[t]};return i},setImageHeight:function(t){var i=t.data("bootstrap-waterfall-pin"),e=this.imgWidth*i.img.height/i.img.width;t.find("img:eq(0)").css({height:e,width:"auto"})},makeImageAvailable:function(t){t.find("img:eq(0)").attr("src",t.data("bootstrap-waterfall-src"))},updatePosition:function(t,i){this.tops[t]+=i.outerHeight(!0)}};i.prototype.load=function(){var i=this;return this.$pins.each(function(){var n=new Image;n.src=t(this).data("bootstrap-waterfall-src");var s=new e(n);i.tasks.push(s),t(this).data("bootstrap-waterfall-pin",s)}),this},i.prototype.run=function(){return this.timerId=setInterval(t.proxy(function(){this.isDone()?this.stop():this.check()},this),40),this},i.prototype.isDone=function(){return 0===this.tasks.length?!0:!1},i.prototype.stop=function(){clearInterval(this.timerId),this.timerId=null,this.deferred.resolve()},i.prototype.check=function(){for(var t=0;t<this.tasks.length;t++){var i=this.tasks[t];i.isLoaded()&&this.tasks.splice(t--,1)}},e.prototype.isLoaded=function(){return this.img.width!==this.initialWidth||this.img.height!==this.initialHeight||this.img.width*this.img.height>1024?!0:!1};var a={getDocHeight:function(){var t=document;return Math.max(t.body.scrollHeight,t.documentElement.scrollHeight,t.body.offsetHeight,t.documentElement.offsetHeight,t.body.clientHeight,t.documentElement.clientHeight)},indexOf:function(t,i){if(null==t)return-1;for(var e=0,n=t.length;n>e;e++)if(t[e]===i)return e;return-1}},h=t.fn.waterfall;t.fn.waterfall=n,t.fn.waterfall.Constructor=o,t.fn.waterfall.noConflict=function(){return t.fn.waterfall=h,this}}(jQuery); // note waterfall should normally be linked as resource in your project $('#waterfall').data('bootstrap-waterfall-template', $('#waterfall-template').html()); let wf = $('#waterfall').waterfall(); let fader = { wh: $(window).height(), full: function() { $('#waterfall .pin').each(function(i, e) { (function(i, e) { setTimeout(function() { fader.check(e) }, i * 150); })(i, e) }) }, check: function(e) { if (fader.wh > e.getBoundingClientRect().top + 60) { $(e).addClass('inView'); setTimeout(function() { $(e).addClass('fix') }, 750) } }, resize:function(){ fader.wh = $(window).height(); fader.full(); }, light: function() { let fst = $('#waterfall .pin:not(".inView")').eq(0); if (fst.is('.pin')) { fader.check(fst[0]) } } }; setTimeout(function() { fader.full() }, 210); $(window) .on('scroll', fader.light) .on('resize', _.throttle(fader.resize, 500,{leading:false,trailing:true}) ); 
 #waterfall .pin { width: calc(50% - 4px); opacity: 0; animation-duration: 0.75s; animation-fill-mode: both; } #waterfall .pin.inView { opacity: 1; animation-name: bounceInUp; } #waterfall .pin.inView.fix { animation: none; } #waterfall .pin a { display: block; padding: 4px 4px 8px; } * { box-sizing: border-box; } .container { text-align: center; } .container #waterfall { max-width: 800px; margin: 0 auto; } @keyframes bounceInUp { from, 60%, 75%, 90%, to { animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); } from { opacity: 0; transform: translate3d(0, 3000px, 0); } 60% { opacity: 1; transform: translate3d(0, -20px, 0); } 75% { transform: translate3d(0, 10px, 0); } 90% { transform: translate3d(0, -5px, 0); } to { transform: translate3d(0, 0, 0); } } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script> <script id="waterfall-template" type="text/template"> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/1.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/2.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/3.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/4.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/5.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/6.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/7.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/8.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/9.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/10.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/11.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/12.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/2.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/6.jpg"> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/1.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/3.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/2.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/4.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/5.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/6.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/7.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/8.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/9.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/10.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/11.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/12.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/2.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/6.jpg"> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/1.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/2.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/3.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/4.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/5.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/6.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/7.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/8.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/9.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/10.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/11.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/12.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/2.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/6.jpg"> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/1.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/3.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/2.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/4.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/5.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/6.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/7.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/8.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/9.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/10.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/11.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/12.png" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/2.jpg" /> </a> </div> <div class="pin"> <a href="javascript:;"> <img src="https://tympanus.net/Development/GridLoadingEffects/images/6.jpg"> </a> </div> </script> <div class="container"> <div id="waterfall"></div> </div> 
Run codeHide result

Its main advantage (and why I chose this route) is that it lazily loads images just before they go to view, which means that you no longer need a button to load more. You can simply put all the images in the <script> (read the plugins - scroll to Q & A - to see why it recommends adding markup).

I also extracted the BounceInUp animation from animate.css , so you don't need to download it.

Note that CSS requires a prefix, and if you want, fiddle has SCSS .

As a rule, I tried to keep it as light as possible, especially from the point of view of javascript listeners (in scroll I only listen to the position of the next element in the list, not for everyone).

Designed as a proof of concept, to point in the right direction.


I know that I didn’t do exactly what you requested (in the sense that it does not allow you to add more items after the first calculation - unfortunately, Bootstrap Waterfall does not currently have update() or addItems() , and I really think they should add one, without recounting existing contacts -
This is no longer the case: Mystist , author of bootstrap-waterfall.js responded to my github request and a method was added. Now I updated jsFiddle by adding an extra button to it, and it works as expected. A huge finger for Mystist from me). Of course, you probably have to adapt the script to your specific case of your project, to how you introduce new elements. In jsFiddle, I decided to create a function that generates a new <script> template on the fly and accidentally adds pins to it.

Regardless, here are the principles that should be followed with this layout:

  • Have an absolute positioning method to position your elements.
  • Hide all items when loading. Animate visible images (in steps) with the desired effect.
  • Put a lock on everything visible to cancel any animation effects when resizing (I used the fix class).
  • Place the listener on scroll and check if the next invisible element has appeared. Animate it when it does, and .fix after the animation finishes.
+8
source

I don’t think you can achieve this effect using css-count css because of how it computes the columns. When you set 'display: none;' on an element, the positioning of the elements in the columns behaves as if it were not. The columns also seem to take into account the height of the element.

My suggestion is, can you change your approach and rather use your own column wrappers and your own javascript / jquery?

In any case, looking at this problem and searching around, I found that your question seems to be a duplicate here, and here is the answer (a similar conclusion for me, but there is also a smart workaround): CSS Column Column Elements Passing Through Columns

+3
source

Source: https://habr.com/ru/post/1266126/


All Articles