I'm making a site where all internal links make the current page fade out and the new page fade in. This works great for me now. The problem is that I'm trying to combine it with the great masonry plugin. On the first pageload masonry does work, but I can't seem to figure out how to re-fire masonry on the newly loaded content via ajax. I should add that all the items from the current masonry get deleted, and then replaced by new ones.
The masonry code is like this:
$container = $('#container');
$container.imagesLoaded(function(){
$container.masonry({
itemSelector: '.item',
transitionDuration: 0
});
});
And the ajax load code is like this:
var newHash = "",
$mainContent = $("#ajaxcontainer"),
$ajaxSpinner = $("#loader"),
$el;
$('.internal').each(function() {
$(this).attr("href", "#" + this.pathname);
});
$(document).on('click', '.internal', function() {
window.location.hash = $(this).attr("href");
});
$(window).bind('hashchange', function(){
newHash = window.location.hash.substring(1);
if (newHash) {
$mainContent.fadeOut(500, function() {
$ajaxSpinner.fadeIn();
$mainContent.load(newHash + " #container", function() {
$ajaxSpinner.fadeOut( function() {
$mainContent.fadeIn(1000);
});
$('.internal').each(function() {
$(this).attr("href", "#" + this.pathname);
});
});
});
};
});
$(window).trigger('hashchange');
Does anyone have any input as to how to achieve this? Thank you very much.
I finally managed to get it to work!
I hope other people will find this helpful so I'm posting it here for future reference.
One of the problems I had, seems to be that I hid the container while the data was loading. I hid it with fadeOut and fadeIn which seems to cause problems with masonry. Insted of hiding it per se, I now animate the opacity to 0 and back to 1 once the data is loaded. The script is as follows:
$(window).bind('hashchange', function(){
newHash = window.location.hash.substring(1);
if (newHash) {
$('#ajaxcontainer').fadeTo(500, 0, function() {
$ajaxSpinner.fadeIn();
$mainContent.empty();
$.get(newHash, function(data){
var $data = $(data).find("#container > *");
$container.prepend($data).imagesLoaded(function(){
$container.masonry( 'prepended', $data, true );
});
$ajaxSpinner.fadeOut( function() {
$('#ajaxcontainer').fadeTo(1000, 1);
});
});
});
};
});
Related
So I am relatively inexperienced with Jquery. What I did was purchase a wordpress theme from theme forest and it has a portfolio section which is supposed to work either as a masonry or grid layout. Neither of which load correctly on first load. The theme uses the Isotope, and I think this link explains what needs to be done: http://isotope.metafizzy.co/appendix.html#imagesloaded
Below is the code that I think calls this function, and the site can be viewed here https://www.roseryflowers.com/bridal-gallery/
jQuery(document).ready(function($) {
/*-- Portfolio --*/
if ($('.portfolio-items').length > 0) {
$container = $('.portfolio-items');
$container.isotope({filter: '.element'});
$(window).trigger('resize');
$('.portfolio-links a').click(function(e){
e.preventDefault();
var $this = $(this);
if ($this.hasClass('active')) {
return false;
}
$this.parents('.portfolio-links').find('.active').removeClass('active');
$this.parent().addClass('active');
$this.addClass('active');
var selector = $this.attr('data-filter');
$container.isotope( {filter: selector} );
});
}
I am at a loss for what to do here. Any help would be appreciated. I even implemented a preloader.
Remove the imagesloaded.js file from your page and change the line with
$(window).trigger('resize');
to
$(window).load(function(){ $(window).trigger('resize'); });
From Isotope's documentation
Unloaded images can throw off Isotope layouts and cause item elements
to overlap. imagesLoaded resolves this issue. imagesLoaded works by
triggering a callback after all child images have been loaded.
initialize Isotope after all images have loaded
var $container = $('#container').imagesLoaded( function() {
$container.isotope({
//options
});
});
This could be the problem
There is a little bit more about...
EDIT
your wrapper tag is ".portfolio-items" then try this
var $container = $('.portfolio-items').imagesLoaded(function () {
if ($('.portfolio-items').length > 0) {
$container = $('.portfolio-items');
$container.isotope({ filter: '.element' });
$(window).trigger('resize');
$('.portfolio-links a').click(function (e) {
e.preventDefault();
var $this = $(this);
if ($this.hasClass('active')) {
return false;
}
$this.parents('.portfolio-links').find('.active').removeClass('active');
$this.parent().addClass('active');
$this.addClass('active');
var selector = $this.attr('data-filter');
$container.isotope({ filter: selector });
});
}
});
You need to be sure to add ImagesLoaded to your project https://github.com/desandro/imagesloaded
I'm currently experiencing some conflict between a hashchange function I have set up and jQuery mobile (used for sliding page transitions).
To demonstrate here's an isolated demo on my server: http://nealfletcher.co.uk/transition/
Click on transition click which slides the relevant page in, as it should and appends the url accordingly: /transition/news.
This is where the problem lies, click on news hash click and this will fire my hashchange function and load in the relevant div, BUT instead of the url being like so: /transition/news/#news-01 the url is being rendered like so /transition/#news-01 which causes problems when navigating to the url.
Is there anyway to force the /news/ to be added before the hash, so I get /transition/news/#news-01 instead of /transition/#news-01?
The relevant jQuery is below, is it at all possible to append /news/ before the hash?
Any suggestions would be greatly appreciated!
jQuery:
$(document).ready(function () {
$(window).hashchange(function () {
var hash = location.hash;
if (hash) {
var element = $('.click-block[data-hook="' + hash.substring(1) + '"]');
if (element) showDetail(element);
}
});
$(document).ready(function () {
$(document).hashchange();
var $container = $('#main-grid, #news-grid');
$(function () {
$container.imagesLoaded(function () {
$container.isotope({
itemSelector: '.grid-block, .grid-break, .hidden',
animationEngine: 'best-available',
filter: '*:not(.hidden), .grid-block',
masonry: {
columnWidth: 8,
gutterWidth: 25
}
});
});
});
$(".click-block").click(function () {
document.location.hash = $(this).attr('data-hook');
});
});
function showDetail(element) {
var newHeight = $('#post-' + element.attr('data-hook')).height();
$('#post-' + element.attr('data-hook')).removeClass('hidden').addClass('grid-break').delay(300).fadeIn('slow');
newHeight = (Math.floor((newHeight + 10) / 230) + 1) * 230 - 10;
$('#post-' + element.attr('data-hook')).css('height', newHeight);
element.children('.up-arrow').fadeIn('slow');
setTimeout(function () {
$('html, body').animate({
scrollTop: $('#post-' + element.attr('data-hook')).offset().top - 90
}, "slow");
}, 1500);
$('#main-grid').isotope();
$('#news-grid').isotope();
}
Just add the section in your data-hook attribute. So for your news links they will be prefixed by news/ like so data-hook="news/news-01"
Now, I would reccomend you to consider using something like http://backbonejs.org/#Router for what you'r doing. Or atleast take a look at https://github.com/browserstate/history.js/
I've searched and serached and nothing really seems to answer what I'm looking for.
I'm pulling in html pages into a div. I finally got it to fadeout, load new href content, then fade in the new content. However, I can't get it to preventDefault on the link.
Here's my code. Any help is greatly appreciated!
$(document).ready(function() {
var url = $(this).attr("href");
$('#container').css('display', 'none');
$('#container').fadeIn(1000);
jQuery('a').click(function(e){
e.preventDefault();
$('a').removeClass('current');
$(this).addClass('current');
$("#container").fadeOut('1000',function(){
$('#container').load(url);
}).fadeIn('1000');
});
})
You need to call this fadeIn inside the load callback.
$(document).ready(function() {
var loading = false;
$('#container').css('display', 'none');
$('#container').fadeIn(1000);
$('a').click(function(e){
if(loading) return false;
e.preventDefault();
loading = true;
var url = $(this).attr("href"),
cont = $("#container"); //cache selector
$('a').removeClass('current');
$(this).addClass('current');
cont.fadeOut(1000, function(){
cont.load(url, function() {
cont.fadeIn(1000, function() {
loading = false;
});
});
});
});
});
So, I got the script from : http://css-tricks.com/dynamic-page-replacing-content/
and edited it to my needs. It works well with "jquery-1.4.4". But the active class assignment for the menu buttons dont work with "jquery-1.5 and later versions".
This is the script:
$(function() {
var newHash = "",
$mainContent = $("#main-content"),
$el;
$("nav").delegate("a", "click", function() {
window.location.hash = $(this).attr("href");
return false;
});
$(window).bind('hashchange', function(){
newHash = window.location.hash.substring(1);
if (newHash) {
$mainContent
.find("#guts")
.fadeOut(600, function() {
$mainContent.hide().load(newHash + " #guts", function() {
$mainContent.fadeIn(600, function() {
});
$("nav a").removeClass("active");
$(" a[href="+newHash+"]").addClass("active");
});
});
};
});
$(window).trigger('hashchange');
});
Than I have this simple ajax loading-spinner code which also doesnt work with the latest jquery:
$(document).bind("ajaxSend", function(){
$('#spinner').fadeIn("fast");
}).bind("ajaxComplete", function(){
$('#spinner').delay(600).fadeOut("slow");
});
I would be grateful for any help.
I think your issue is here:
i am not sure but try if this works for you.
$(" a[href='"+newHash+"']").addClass("active");
// ^-----------^-----------you have missed the " ' " single quotes
Currently coding a mates portfolio and not to my surprise the code isn't loading in IE!
I'm coding it using standard AJAX, here's the relevant jQuery:
//ajax shtuff
$(window).load(function() {
// Ajax Cache!
$.ajaxSetup ({
cache: false
});
var $loadW = '<div id="whiteLoader" />';
var $loadurl = $('.current').attr('href');
// Initial Page Load
$('#con').prepend($loadW);
$('#main').fadeOut('slow', function() {
$(this).load($loadurl + ' .page', function() {
$(this).parent().find('#whiteLoader').fadeOut('slow', function() {
$(this).parent().find('#main').fadeIn('slow').css({background: 'red'});
$(this).remove();
});
});
});
$('nav ul li a').each(function() {
$(this).click(function(e) {
var $loadW = '<div id="whiteLoader" />';
var $loadurl = $(this).attr('href');
// Prevent default hotlink
e.preventDefault();
// Add the current state
$('*').removeClass('current');
$(this).addClass('current');
// Load the Page
$('#main').fadeOut('slow', function() {
$('#con').prepend($loadW);
$('#main').load($loadurl + ' #main', function() {
$('#whiteLoader').fadeOut('slow', function() {
$('#main').fadeIn('slow');
$(this).remove();
});
});
});
});
});
});
Literally have no idea why this doesnt work lol, here's a link to the live page (I've put the background as red just to show you the area.)
Also the reason the initial page is using the 'this' method is because I was testing it both ways.
http://212.7.200.35/~tfbox/zee/
have you tried
$(document).ready(function() {
// Stuff to do as soon as the DOM is ready;
});
instead of window.load?
Often IE has trouble styling / selecting any of the new HTML5 elements such as section and nav. Try using something like this or simply using a div