I'm trying to set up Masonry with Infinite Scroll, it works but it currently loads all items and then when I click on the next page link it loads them all again.
Nav:
<div class="more" id="navigation">
MORE IDEAS
</div>
JS:
$(document).ready( function() {
(function() {
// Main content container
var $container = $('.grid');
// Masonry + ImagesLoaded
$container.imagesLoaded(function(){
$container.masonry({
itemSelector: '.grid-item',
columnWidth: '.grid-sizer',
gutter: '.gutter-sizer',
percentPosition: true
});
});
// Infinite Scroll
$container.infinitescroll({
// selector for the paged navigation (it will be hidden)
navSelector : "#navigation",
// selector for the NEXT link (to page 2)
nextSelector : "#navigation a",
// selector for all items you'll retrieve
itemSelector : ".grid-item",
},
// Trigger Masonry as a callback
function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true );
});
});
// Pause Infinite Scroll
$(window).unbind('.infscr');
// Resume Infinite Scroll
$('.more a').click(function(){
$container.infinitescroll('retrieve');
return false;
});
})();
});
Content:
<div class="grid">
<div class="grid-sizer"></div>
<div class="gutter-sizer"></div>
<div class="grid-item">Item 1</div>
<div class="grid-item">Item 2</div>
<div class="grid-item">Item 3</div>
<div class="grid-item">Item 4</div>
<div class="grid-item">Item 5</div>
<div class="grid-item">Item 6</div>
</div>
Currently it loads all items, 1 to 6, then when I click the Load More button it loads items 1 to 6 again. I've looked on the couple of other questions which are similar to this but they are different circumstances. It's probably something simple, any help would be most appreciated.
Figured it out.
You need to take part of the content you want loaded second out and put it in another html page. Then you need to set the navigation link to go to that page. As it was just set to ?page=2 it was just loading the same page again.
Related
I created three onclick trigger functions that trigger three separate divs in a larger div "main". For some reason, the function only works after one click, then I have to refresh the page.
For example, if I click to trigger the sports function, I have to refresh the page before I can use the news button. From there I have to refresh the page. How do I get the main div to reload before I trigger a second or third event? I've tried location.reload(), but that doesn't seem to work.
<div id="main">
<div id="news">
<h2 id="newsbtn"> News </h2>
</div>
<div id="interactive">
<h2 id="interactivebtn"> Interactive</h2>
</div>
<div id="sports">
<h2 id="sportsbtn"> Sports </h2>
</div>
</div>
$( "#newsbtn" ).click(function() {
$("#sports").fadeOut( "slow", "linear" ),
$("#interactive").fadeOut( "slow", "linear" );})
$( "sportsbtn" ).click(function() {
$("#interactive").fadeOut( "slow", "linear" ),
$("#news").fadeOut( "slow", "linear" );})
$( "#interactivebtn" ).click(function() {
$("#sports").fadeOut( "slow", "linear" ),
$("#news").fadeOut( "slow", "linear" );})
$( "#news" ).click(function() {
$("#sports").fadeOut( "slow", "linear" ),
$("#interactive").fadeOut( "slow", "linear" );})
;})
It sounds like you are basically trying to make an accordian.
That being the case, you're currently hiding all the other elements when one element is clicked. After that, you cant click one of the other elements because you have hidden them.
Generally, for an accordian, each element would have a container with a header and a content area and only the content area would be hidden leaving the header to be clicked
Here is a simple (and not perfect) example, if this is indeed what you are wanting:
$("#main").on('click', '.selectable-container .header', function() {
var $container=$(this).closest('.selectable-container');
$('.selectable-container').not($container).find('.content').fadeOut("slow", "linear");
$container.find('.content').fadeIn("slow", "linear");
})
.selectable-container .content{
display:none;
}
.selectable-container .header{
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<div class="news selectable-container">
<div class="header">news</div>
<div class="content">news content</div>
</div>
<div class="interactive selectable-container">
<div class="header">header</div>
<div class="content">header content</div>
</div>
<div class="sports selectable-container">
<div class="header">sports</div>
<div class="content">sports content</div>
</div>
</div>
I am calling an isotope layout for multiple containers on the same page. The catch it I would like each container ID to the be the same. Using http://isotope.metafizzy.co v.2.1.0
Isotope will work for the first block, but doesn't trigger for the second block. My feeling is once isotope layout hits the first ID of the first container it stops and doesn't look for the same container again. I've tried using .each() - doesn't seem to want to work however.
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
I then need to call another isotope block layout again:
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
Full HTML would look like this:
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
<div id="isotope-cat-list">
<div class="grid-sizer"></div>
<div class="box">
<h1>TITLE</h1>
</div>
<div class="box">
<h1>TITLE</h1>
</div>
</div>
Obviously there are more elements in those .box elements but for simplicity sake I whittled it down. The reason for multiple calls is they will be for different categories and have other elements in between then and I'd rather not have to call a bunch of container ID's.
When I try to trigger the #isotope-cat-list in my .js library it will run for the first block - but won't trigger for the second block. I've tried doing some jQuery .each() but that didn't work.
Here's the JS:
var mainEl = $('#isotope-cat-list');
mainEl.isotope({
animationEngine: 'best-available', //CSS3 if browser supports it, jQuery otherwise
itemSelector: '.box',
animationOptions: {
duration: transitionDuration
},
containerStyle: {
position: 'relative',
overflow: 'visible'
},
masonry: {
columnWidth: columnWidth,
gutter: 1
}
});
I've tried doing .each():
var mainEl = [$('#isotope-cat-list')];
$.each(mainEl, function (j) {
this.isotope({
animationEngine: 'best-available', //CSS3 if browser supports it, jQuery otherwise
itemSelector: '.box',
animationOptions: {
duration: transitionDuration
},
containerStyle: {
position: 'relative',
overflow: 'visible'
},
masonry: {
columnWidth: columnWidth,
gutter: 1
}
});
});
But it still doesn't trigger for the second HTML block. Any help here would be much appreciated! Thanks!
As I stated, ID's are unique. You can use a class multiple times like so ( some of your functions are missing so I had to modify your code for that reason). You are calling isotope using v1.56 options, not v2.
Updated code
jsfiddle
var mainEl = $('.isotope-cat-list');
mainEl.isotope({
itemSelector: '.box',
transitionDuration: '0.3s',
masonry: {
columnWidth: '.grid-sizer',
gutter: 10
}
});
You are using isotope V2 and it only uses css3 for animations, therefore you should not apply animationEngine or animationOption. Also you are using "grid-sizer" and that should be what you apply in your columnWidth. E.g. columnWidth: '.grid-sizer'. Also the containerStyle is position: relative as a default, therefore it is useless to say it in the options. Also the gutter is pointless in your case as you can simply use margins in css for your items.
For your question you'd do:
var mainEl = $('.isotope-cat-list');
mainEl.isotope({
itemSelector: '.box',
masonry: {
columnWidth: '.grid-sizer'
}
});
var mainEl2 = $('.isotope-cat-list-2');
mainEl2.isotope({
itemSelector: '.box',
masonry: {
columnWidth: '.grid-sizer'
}
});
The nature of the elements are that each one will be varied in height (due to image and the title) and its height is unknown before applying masonry. Though the width of each element is fixed with .col-lg-3.
On the rendered page where each row has 4 elements, the 5 element is visually on a row on its own and the 6, 7, 8 got pushed down to 3rd row.
html code
<div class="section-details">
<div class="container">
<div class="">
<div class="masonry" id="elements" data-reference="0">
<!-- elements will be pulled over dynamically -->
</div>
</div>
</div>
</div>
and the content of each new element is wrapped in something like the following
<div class="col-lg-3 element">
</div>
css
.element {
padding: 10px 10px 0px;
}
javascript code
// layout the elements
var layout = function(elements, $container, selector) {
$container.imagesLoaded(function () {
$container.masonry({
itemSelector: selector,
columnWidth: selector,
isAnimated: true,
animationOptions: {
duration: 750,
easing: 'linear',
queue: false
}
}).append(elements).masonry('appended', elements, true);
});
};
and it's got called in the following way
layout(elements, $('#elements'), '.element');
So anything could go wrong here?
Debugged into the masonry source code and figured out the cause, it's how the elements got prepared that matters - each of the element that got pushed to the elements array should be an HTMLElement. And once I got that fixed, the issue was gone.
I have the following codes to create a top sliding admin panel, that will appear from the very top of the page. This sliding panel will be activated but clicking on the button "#tp-button2".
However, I would like to add one more sliding panel and call it #toppanel2.
Behavior
tp-button2: when click, it will either show or hide toppanel, and if toppanel2 is "show", to slide it back into position before it slides out toppanel
tp-button3: same behavior as above but for toppanel2
Current Situation: I'm using toggleClass which is easy for just 1 panel since it's to turn and off, but I'm not sure the algorithem to achieve the above, and i've tried long methods including addClass and removeClass and it's not working out because removeClass doesn't work.
This is what i'm using for single toggleClass
Original CSS
#tp-button2,tp-button3 {
}
.toppanel {
height: 150px ;
top:-150px;
background-color: #FFFFFF !important;
position: '.$dimensionposition.' !important;
}
.toppanel2 {
height: 75px ;
top:-75px;
background-color: #F1F1F1 !important;
position: absolute !important;
}
.show {top:0px}
.tp-relative {position: relative;padding-bottom: 150px;}
.tp-relative2 {position: relative;padding-bottom: 75px;}
</style>
Original Javascript
var $j = jQuery.noConflict();
$j(function() {
$j( "#tp-button" ).click(function(){
$j(".toppanel").toggleClass("show", 900, "easeOutBounce");
$j("#tp-relativeblock").toggleClass("tp-relative", 900, "easeOutBounce");
});
});
</script>
I've attempted something like this
var $j = jQuery.noConflict();
$j(function() {
$j("body").on("click", "#tp-button2", function(){
if ($j("#toppanel").hasClass("show")) {
alert("tp-button2 remove class");
$j("#toppanel").removeClass("show", 900);
$j("#tp-relativeblock").removeClass("tp-relative", 900);
} else {
alert("tp-button2 addClass");
$j("#toppanel2").removeClass("show", 900).delay(900).queue($j("#tp-relativeblock").addClass("tp-relative", 900));
$j("#tp-relativeblock").removeClass("tp-relative2", 900).delay(900).queue($j("#toppanel").addClass("show", 900));
}
});
$j("body").on("click", "#tp-button3", function(){
if ($j("#toppanel2").hasClass("show")) {
alert("tp-button3 removeClass");
$j("#toppanel2").removeClass("show", 900);
$j("#tp-relativeblock").removeClass("tp-relative2", 900);
} else {
// Here i attempt to just bring down panel 2 without closing panel 1 to see whether there's code above that's wrong but it's not working too.
alert("tp-button3 addClass");
$j("#tp-relativeblock").addClass("tp-relative2", 900);
$j("#toppanel2").addClass("show", 900)
}
});
This is what i have on body
<div id="tp-button"><i class="'.$iconstop.'"></i></div>
<div id="toppanel" class="toppanel">
<div id="tp-container">
<div class="tp-s1">
THIS IS PANEL 1 COLUMN 1
</div>
<div class="tp-s2">
THIS IS PANEL 1 COLUMN 2
</div>
<div class="tp-s3">
THIS IS PANEL 1 COLUMN 3
</div>
<div class="tp-s4">
THIS IS PANEL 1 COLUMN 3
</div>
</div>
</div>
<div id="toppanel2" class="toppanel2">
<div id="tp-container">
<div class="tp-s1">
PANEL 2
</div>
<div class="tp-s2">
PANEL 2
</div>
<div class="tp-s3">
PANEL 2
</div>
<div class="tp-s4">
PANEL 2
</div>
</div>
</div>
<div id="tp-relativeblock"></div>
I understand addClass and removeClass and what it does but sometimes removeClass doesn't remove tp-relative from tp-relativeblock so it doesn't move back up to space.
Click Button2:
toppanel slide down Success
relativeblock slidedown Success
Second Button 2 Click:
toppanel slides up to 0px Success
remove tp-relative from #tp-relativeblock failed
Click button3:
Nothing Happens
Button2 also became disabled
Amature here to javascript and jquery, so will appreciate all help i can to achieve this.
My objective is for panel 1 to show "Login TO Website" and panel 2 to show "Register To Website"
THANK YOU IN ADVANCED!!
This is the jQuery I use to add and remove classes
To add:
$("#some-id").toggleClass('class-name', 'add');
To Remove:
$("#some-id").toggleClass('class-name', 'remove');
In this fiddle toggleClass is used to trigger css animations
I'm using a combination of Masonry, Will Paginate, and Infinite Scroll. Masonry and Will Paginate are working fine but I can't seem to get the Infinite Scroll to work.
I have a feeling that it might be that my selectors are wrong but I am still in the dark after trying different variations.
Script
<script type="text/javascript">
$(function(){
var $container = $('#container');
$container.imagesLoaded( function(){
$container.masonry({
itemSelector : 'item'
});
});
});
// infinitescroll() is called on the element that surrounds
// the items you will be loading more of
$('#container').infinitescroll({
navSelector : '.pagination',
// selector for the paged navigation (it will be hidden)
nextSelector : '.pagination .next_page a',
// selector for the NEXT link (to page 2)
itemSelector : '#container .item'
// selector for all items you'll retrieve
},
// trigger Masonry as a callback
function ( newElements ) {
var $newElems = $( newElements );
$container.masonry( 'appended', $newElems );
}
);
</script>
Navigation
<div class="pagination">
<span class="previous_page disabled">← Previous</span>
<em>1</em>
2
3
4
5
6
7
<a class="next_page" href="/?page=2" rel="next">Next →</a>
</div>
Content
<div id="container" class="masonry" style="position: relative; height: 0px;">
<script type="text/javascript" src="/javascripts/jquery.min.js?1329440016">
<script type="text/javascript" src="/javascripts/jquery.masonry.min.js?1327461530">
<script type="text/javascript" src="/javascripts/jquery.infinitescroll.min.js?1324335816">
<div class="item">
Try moving your infinitescroll inside. Namely, try the following:
$(function(){
...
$('#container').infinitescroll({
...
);
});
Hope that helps.
Your nextSelector needs to be .pagination a.next_page, not .pagination .next_page a.