masonry.js div reset when select link - javascript

Hey so here's the website I'm working http://trevormsmith.com/linx/art.html
Trying to build a filter system (in the footer), and when you click on the specific categories (minimalist, typographic, abstract) masonry resets the images into a single column, instead of the grid. If you resize the browser, it'll readjust to normal.
This is what I have calling masonry to the containers with the images
Also, when I set the #minimalist, #typographic, #abstract to display:show instead of display:none (which it needs to be), the layout is fine and it works smoothly.
Any suggestions?
Edit: So here's the code that is working only for #minimalist, except the masonry is not being triggered and the images stay floated instead of tiling:
EditEdit: here's the current code, #containers fade in as a single column instead of grid layout: http://jsfiddle.net/T6SDb/1/
Calling the masonry:
$( function() {
$('#container-all, #minimalist, #typographic, #abstract').masonry({
itemSelector: '.item, .item-m, .item-t, .item-a',
columnWidth: 7 }); });
And then the fadein/fadeout for the filter:
$('#btn-all').click(function(e){
$('#minimalist, #typographic').fadeOut('slow', function(){
$('#container-all').delay(1000).fadeIn('slow', function(){
});
});});
$('#btn-m').click(function(e){
$('#container-all, #typographic').fadeOut('slow', function(){
$('#minimalist').delay(1000).fadeIn('slow', function(){
$('#container-all').masonry('layout');
});
}); });
$('#btn-t').click(function(e){
$('#container-all, #minimalist').fadeOut('slow', function(){
$('#typographic').delay(2000).fadeIn('slow', function(){
$('#container-all').masonry('layout');
});
}); });
$('#btn-a').click(function(e){
$('#container-all, #typographic, #minimalist').fadeOut('slow', function(){
$('#abstract').delay(2000).fadeIn('slow', function(){
$('#container-all').masonry('layout');
});
}); });

Try calling masonary('layout') after fading in the selected images, i.e. for the container-all (from your filter.js file) try this:
$('#btn-all').click(function(e){
$('#minimalist, #typographic').fadeOut('slow', function(){
$('#container-all').delay(1000).fadeIn('slow', function(){
$('#container-all').masonry('layout');
});
});
});
I'm only testing this from the JavaScript console so you might need to tweak the timing / positioning. I'm doing it when the fade is complete, you might want to try doing just after the start of the fade.
Edit
It may be because of the way your containers are put together and how you start masonary, perhaps you can do this in your main source:
var mason;
$( function() {
mason = $('#container-all, #minimalist, #typographic, #abstract').masonry({
itemSelector: '.item, .item-m, .item-t, .item-a',
columnWidth: 7});
});
});
Then later you can use mason.masonary('layout') in each of your click functions rather than referring to a single container, i.e. for the first one try:
$('#btn-all').click(function(e){
$('#minimalist, #typographic').fadeOut('slow', function(){
$('#container-all').delay(1000).fadeIn('slow', function(){
mason.masonary('layout');
});
});
});
Depending when you want things to appear and rearrange you might want to fadeTo a certain value then do the layout and then complete the fade (or you could do that on a delay too).
Maybe look at the Masonary functions hide and reveal to remove given elements.
It may also make things easier to work with the items themselves rather than the containers (since everything gets rearranged) and just have one outside container for everything.
I'd also suggest trying a simpler example (maybe just colored divs or something), working with that, and posting it if you still have issues. There may be some interaction between the libraries you are using.
Edit 2
Added Fiddle, that uses the separate mason variable above. It works but, again, you might need to do something about the timing of the fade in / fade out -- of course you can't arrange the things until they're visible which is an issue. I'm not sure of the best way to fix that.

Related

ScrollTo: targeting specific buttons in a navbar

Got an issue with a navbar I'm creating for a WordPress site. Some of the links are meant to scroll down to different places on the homepage and some are outside links to other places on the site. Something like this:
<div class="main-navigation">
<ul>
<li class="link1">Link 1
<li class="link2">Link 2
</ul>
</div>
Basic stuff.
So if I add the following Javascript in the footer....
jQuery(document).ready(function() {
jQuery('.main-navigation a' ).click(function(){
jQuery.scrollTo( this.hash, 1000, { easing:'swing' });
return false;
});
Link 2 will scroll down but since Link 1 isn't supposed to scroll, if you click on it, nothing happens like it's a null link.
I thought I could change the reference to something like
jQuery('.main-navigation a.link2' ).click(function(){
So only link 2 does the scrolling, but that just makes it jump to the page like an old anchor tag trick in the 1990's.
Tried a few variations of the same idea, and nothing clicked. Anyone know what the right code would be to target just the buttons that need to have the scrolling?
Building from itsgoingdown's answer. The animation is ignored because the default link event still fires. If you pass the event and also prevent the default, you'll be set. See below.
$(document).ready(function() {
$('.main-navigation a[href^="#"]' ).click(function(event) {
// Prevent default link action
event.preventDefault();
// Grab location to send to
var href = $(this).attr('href');
// Scroll the page, animated
$('html, body').animate({
scrollTop: $(href).offset().top
}, 700);
});
});
Here is a live JSFiddle to show as well.
https://jsfiddle.net/y3nutj22/5/
Thanks to the both of you. I finally figured it out and in a sense, you're both right. However, neither of your codes produced the scrollTo effect. While '.main-navigation a[href^="#"]' was partially correct, my issue....and I finally realized it this morning....was I hard coded in the URL's in WordPress' menu feature as a complete URL. So just using '#' wouldn't work. Also, since it's WP, I can't use $'s in the code, Have ot use jQuery, of course.
This is the code that did the trick.
jQuery(document).ready(function() {
jQuery('.main-navigation a[href^="http://path.to.url/#"]' ).click(function(){
jQuery.scrollTo( this.hash, 1000, { easing:'swing' });
return false;
});
with path.to.url representing the actual URL, of course.
Thanks again!

How to FORCE a resize event that will run all resize functions

I am using Masonry.js to create a masonry style blog. The problem with this is, when I click 'Article' for example, my JS makes everything but an article disappear. Instead of all the articles filling in the gaps that were previously filled with other post types, they just stay in the same position.
Once I resize the window Masonry.js does its thing and every gap becomes filled with the articles. My question is how to FORCE this to happen without having to resize the window manually?
Note:
I have tried this link
Forcing windows resize to fire
This will not work.
$(window).resize(function(){
$('span').text('event fired!');
});
$('button').click(function(){
window.dispatchEvent(new Event('resize'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button>Fire event</button>
<span></span>
This must work (I'm using it right now)
$(window).trigger('resize');
Hope this helps.
EDIT
Note that's jQuery syntax.
EDIT 2
i make a research of masonry.js (I don't meet it before this post), and I think that you can solve this problem like this:
$(window).on('resize', function () {
$('#element').masonry('reloadItems');
});
$(window).trigger("resize");
Good luck
I managed to fix this.
$('#article-options li').on('click', function() {
setTimeout(function() {
var $grid = $('#blog-container').masonry({
columnWidth: 80
});
// change size of item by toggling gigante class
$(this).toggleClass('gigante');
// trigger layout after item size changes
$grid.masonry('layout');
}, 200);
});
Each 'section' of the blog of mine is in a ul called article options so when an option is clicked (therefore changed) it will run this function.
I have set a timeout as JS was running a bit behind and making me click twice for the code to run.
I defined a new masonry grid, I defined this as the overall blog container which holds all posts. I then had code in place which recognised the click function on a section and toggled a class which pops everything back into their correct positioning.
As for details, i'm not too sure as this is not my module. If anyone has any valuable information that might help others, comment and I will update my answer. Thanks everyone.

jQuery functions not working after Infinite Scroll (AJAX) with Masonry

this may get complicated so I will try to explain my situation as best as I can.
I am using this jquery plugin http://www.infinite-scroll.com/ along with masonry: http://masonry.desandro.com/
Everything is working fine.
However, I'm trying to make some info relating to each post appear when you hover over a post. Here is my code:
$(".main").hover(function(){
$(this).next(".info").slideToggle("fast");
});
This only works on the first page content and not the extra content that is loaded by the infinite scroll.
So I tried adding the function to the callback of my masonry code:
// 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);
});
$(".main").hover(function(){
$(this).next(".info").slideToggle("fast");
});
});
(Excuse me if I'm doing this completely wrong, I have never worked with Ajax before and am merely experimenting)
This made the hover function work on the new extra content loaded by Infinite scroll, however it then conflicted with the original content.
So, what is the best way to implement my hover function so it will work properly for all posts loaded before and after the Ajax call?
Thanks.
EDIT:
Solved the problem by changing my method to this:
$(document).on("click",".main",function(){
$(this).next(".info").slideToggle("fast");
});
http://api.jquery.com/on/
I will leave the original question here incase someone with a similar problem finds it useful.
$(document).on("click",".main",function(){
$(this).next(".info").slideToggle("fast");
});
For latest version of http://www.infinite-scroll.com/ along with masonry: http://masonry.desandro.com/ following code worked for me:
$grid.on( 'append.infiniteScroll', function( event, response, path, items ) {
$(this).next(".info").slideToggle("fast");
// OR your code you want to load after infinite scroll loads
});
Check for more here https://infinite-scroll.com/events.html#append

Fancybox - Modify javascript to add options

I have the following Fancybox declarations in my page:
<script type="text/javascript">
$(document).ready(function() {
$(".fancybox").fancybox().hover(function() {
$(this).click();
});
$("#fancybox-outer").fancybox().mouseleave( function() {
$("#fancybox-overlay").click();
});
});
</script>
I need to reduce the size of the image used by the modal box and I believe I can do that by setting the "autoDimensions", "width", and "height" options available with Fancybox, I just don't know how to integrate that with the hover function, since there isn't an option in Fancybox to specify a function for a hover event. (I hope this is making sense.)
Anyhow, does anyone know how I can modify the above javascript to control the width and height?
Thanks!
Sorry but images in fancybox don't use "autoDimensions", "width", and "height" API options. Those options are for ajax, iframe or inline content only.
Images in fancybox are displayed either, re-sized to fit into the viewport (when autoScale is set to true) or in their original size (when autoScale is set to false). If the original size is bigger than the height of the viewport, then you have to scroll down the parent page to see the whole image.
The only way you can re-size images in fancybox other than above is using jQuery css() API (which, I wouldn't advise ... it produces an odd behavior). You can call it using fancybox's callback option onComplete like:
<script type="text/javascript">
$(document).ready(function() {
$(".fancybox").fancybox({
'onComplete': function(){
$("#fancybox-outer, #fancybox-content").css({'width':300,'height':150});
}
}).hover(function() {
$(this).click();
});
$("#fancybox-outer").fancybox().mouseleave( function() {
$("#fancybox-overlay").click();
});
});
</script>
Note that options mentioned above are for fancybox v1.3.x.
Use it at your own risk.
you can always add code to document.ready to trigger every time. so just check for the event and resize.
or since the elements are hidden at first, you can get the event trigger using the show event
Check for the event onstart. onstart will be called right before attempting to load the content, and you can add your resize operations there.

Fade in Ajax content after it's fully loaded

My current solution gets some content via AJAX, Inserts it into a DIV then hides it and fade it in.
The issue with that is the content contains images and an iframe, The solutions flickers and the fadeIn doesn't look smooth.
What i'd like to do is to only fadeIn after the iframe and pictures are fully loaded.
How to do that?
This will wait until all child content has finished loading:
$("#wrapperDivID").load(function (){
// do something, e.g.
$(this).fadeIn();
});
See .load().
In your specific case the following should work:
$('#content').load('/echo/html/',data, function() {
alert('fired');
});
I would change the duration for fadeIn so that it will take little long.
$("#content").load("getform.php"), function() {
$(this).fadeIn(1500); // or another bigger number based on your load time
});
If you know what all images are going to be in the page, Preload all those images in the page where you have the div "content", so that you will save some loading time.
If you use $.ajax to get the HTML you can wrap the resulting HTML like below:
$.ajax('some/path/to.html',{
'success':function(html){
var result = $(html).load(function(){
$('#content').fadeIn()
});
$('#content').html(result);
}
});
jsfiddle example
another way you can do this:
$( "#content" ).fadeOut(200, function() {
$(this).load( url, function() {
$(this).fadeIn(200);
});
});
change the fadeIn and Out times to whatever is good for you.

Categories