jQuery script delayed by AJAX request - how to fix it? - javascript

I'm making a simple responsive Wordpress Theme and I want only one page there, and the content loaded via AJAX, so I have an AJAX function:
jQuery(document).ready(function(){
jQuery.ajaxSetup({cache:false});
jQuery("#mainnav a").click(function(){
var post_link = jQuery(this).attr("href");
jQuery("body").load(post_link);
return false;
});
});
It's meant to load entire pages content (entire body) on clicking menu links. And it works well.
But the problem is I have a jQuery script responsible for centering content div:
(function (jQuery) {
jQuery.fn.centerAlign = function() {
return this.each(function(i){
var w = jQuery(this).width();
var ow = jQuery(this).outerWidth();
var ml = (w + (ow - w)) / 2;
var h = jQuery(this).height();
var oh = jQuery(this).outerHeight();
var mt = (h + (oh - h)) / 2;
jQuery(this).css("margin-top", "-" + mt + "px");
jQuery(this).css("top", "50%");
jQuery(this).css("margin-left", "-" + ml + "px");
jQuery(this).css("left", "50%");
jQuery(this).css("position", "absolute");
});
};
})(jQuery);
jQuery(document).ready(function() {
jQuery("#content").centerAlign();
});
That script centers the #content div at reload instatly, so I mean there is no delay. The div is centered from the start.
Problem is when I combine that scripts, because after AJAX loads the entire body, #content div is not positioned for ~1 second (in top-left corner of the page) and then it comes back to its place. So jQuery script works with a delay.
I coulnd't find a solution for that problem, .on and .live don't work for me. I think I could just load each page content into a #content div, not entire "body", but I don't know how to make it.
I'd appreciate if you can help me with that, so it will just resize the #content div with animation, not position it from start.
EDIT:
Ok, I ended up with such code:
jQuery(function(){
jQuery("#mainnav a").click(function(e){
var content=jQuery("#content");
jQuery.ajax({
url: jQuery(this).attr('href'),
dataType: "HTML",
beforeSend: function(){
content.empty();
},
success: function(){
content.load();
},
error : function(){
content.html("<p>Przepraszamy, ale strona jest chwilowo niedostępna</p>");
},
});
e.preventDefault();
})
})
It should work, but the problem is that I can't figure out what should I put in that lines:
success: function(){
content.load();
It workd up to that point. I clears the #content div but when I put content.load("#content"); it loads entire page, with menu and footer. And I want to load just #content content.
EDIT:
Ok. Firebug shows that this code is working, but there is nothing shown within the #content div in broswer window.
jQuery(function(){
jQuery("#mainnav a").click(function(e){
var content=jQuery("#content");
var href=jQuery(this).attr('href');
var text = jQuery(this).find('#content').html();
jQuery.ajax({
url: jQuery(this).attr('href'),
dataType: "HTML",
beforeSend: function(){
content.empty();
},
success: function(){
content
.html(text)
.centerAlign();
},
error : function(){
content.html("<p>Content Unavailable</p>");
},
});
e.preventDefault();
})
})

I think you're on the right track with your new code, you just need to fill out your success function:
success: function( html ){
html = jQuery(html).find('#content').html();
content.html(html).centerAlign();
},
or perhaps (using th1rdey3's idea):
success: function( html ){
html = jQuery(html).find('#content').centerAlign().html();
content.html( html );
},

You could centerAlign #content before placing it inside body. Something like this
var $div = jQuery('<div/>').load(post_link);
$div.find('#content').first().centerAlign();
jQuery('body').html($div.html());
or only loading the content part
var $div = jQuery('<div/>').load(post_link);
jQuery('#content').first().html($div.find('#content').first().html());

Related

AJAX load when reach bottom of container

I can't figure this problem out.
I use this JS call to load ajax content when I arrive at the bottom of the page:
$(window).scroll(function() {
if($(window).scrollTop() + window.innerHeight == $(document).height() ) {
and it works well, but now I want to change for loading the content when I reach the bottom of my container... I am trying this:
$(window).bind('scroll', function() {
if($(window).scrollTop() >= $('#postswrapper').offset().top + $('#postswrapper').outerHeight() - window.innerHeight) {
It loads the content when I reach the bottom of the container, but it loads it like 5 times... It's like as if it does a loop 5 times each time.
I want it to load ONCE, then when I go back DOWN the page and I reach the "NEW BOTTOM" of the container, load data 1 more time...etc
I tried many variables, but I can't figure it out. Any suggestions?
FULL AJAX CODE
$(window).bind('scroll', function() {
if($(window).scrollTop() >= $('#postswrapper').offset().top + $('#postswrapper').outerHeight() - window.innerHeight) {
$('div#loadmoreajaxloader').show();
$.ajax
({
url: "loadmore.php",
method: "get",
data: { page: pageNumber, perpage: perPage, search: "<?=$search?>", blogtag: "<?=$blogtag?>"},
success: function(html)
{
if(html)
{
$("#postswrapper").append(html);
$('div#loadmoreajaxloader').hide();
pageNumber++;
}
else
{
$('div#loadmoreajaxloader').html('<center>No more posts to show.</center>');
}
}
}); // close AJAX
} // close if()
}); // close $(window)
Scroll top is executed few times after you have the set true for the condition:
if($(window).scrollTop() >= $('#postswrapper').offset().top + $('#postswrapper').outerHeight() - window.innerHeight)
Here is a test fiddle for the window scroll, it always fires when you move the scroll and your condition does not limit the inner scope to execute only once.
test scrool event
Edit: simplest way is to use a lock while the ajax request is executing and while you are updating the UI with new content.
Why build something like this yourself when there are plenty of libraries out there? Just use an infinite scroll library that meets your needs. As you already use jQuery:
http://www.sitepoint.com/jquery-infinite-scrolling-demos/
But that's not the answer to your question. You should add a boolean to check if you're already loading new content. Let's say: loading. Initially set this boolean to false. If you request new data, set the boolean to true and in the check scroll statement add a check for this boolean. After adding the newly loaded content set the boolean to false again.
Fully working code:
var loading = false;
$(window).bind('scroll', function() {
if(!loading && $(window).scrollTop() >= ($('#postswrapper').offset().top + $('#postswrapper').outerHeight() - window.innerHeight)) {
loading = true;
$('div#loadmoreajaxloader').show();
$.ajax({
url: "loadmore.php",
method: "get",
data: {
page: pageNumber,
perpage: perPage,
search: "<?=$search?>",
blogtag: "<?=$blogtag?>"
},
success: function(html) {
if(html) {
$("#postswrapper").append(html);
$('div#loadmoreajaxloader').hide();
pageNumber++;
loading = false;
} else {
$('div#loadmoreajaxloader').html('<center>No more posts to show.</center>');
}
}
}); // close AJAX
} // close if()
}); // close $(window)

Split divs with class from html to be used by script

I am trying to build my own 'infinite scroll' so I have more control than using a plugin.
I currently have the below:
$(window).scroll(function(){
if ($(window).scrollTop() == $(document).height() - $(window).height()){
loadNew();
}
});
function loadNew(){
var next = $('a.next').attr('href');
$.ajax({
url: next,
success: function(html){
** GET ALL '.grid-item' TO USE BELOW**
var $newElems = $( **ALL .grid-item** ).css({ opacity: 0 });
$newElems.imagesLoaded(function(){
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true );
});
}
});
return false;
}
This is so far triggering when the user scrolls to the bottom of the page, its then getting the 'next' URL from the pagination and returning the full HTML of the page in the success call.
As you can see in my code, I want to get all divs with the class '.grid-item' to be used by the code below.
I am really struggling to get the '.grid-item' divs seperated to be used.
Is anyone able to explain how I can do this?
What you can do is convert the returned html to a jQuery object so that you can parse it using find() to get the relevant elements. This is done easily by wrapping the html like this, $(html), but if there is a doctype declaration then that will break it. What I normally do is make sure I've only got data that starts from the opening html tag.
Try this...
function loadNew(){
var next = $('a.next').attr('href');
$.ajax({
url: next,
success: function(html){
html = html.substr("<html"); // remove the doctype
var $newElems = $(html).find(".grid-item").css({ opacity: 0 });
$newElems.imagesLoaded(function(){
$container.append($newElems).masonry("appended", $newElems, true);
$newElems.css({ opacity: 1 });
});
}
});
return false;
}
Also, you need to first append the elements to the container, and then tell masonry that you've done so. The masonry appended call doesn't actually append anything.

Masonry items not reloaded when cliking ajax load more button

Hi everyone i have one problem about masonry items.
I have created this DEMO from codepen.io
In this demo you can see there is this javascript code:
$(window).load(function()
{
$( function() {
var $container = $('.posts-holder');
$container.masonry({
isFitWidth: true,
itemSelector: '.kesif-gonderi-alani'
});
});
});
I show only 10 posts when a page is opened. If user want to show other 10 posts then user needs to click (show more button). I created this ajax function for show more posts.
$('.showmore').live("click",function(event)
{
event.preventDefault();
var ID = $(this).attr("id");
var P_ID = $(this).attr("rel");
var URL=$.base_url+'diger_fotograflar_ajax.php';
var dataString = "lastid="+ ID+"&profile_id="+P_ID;
if(ID)
{
$.ajax({
type: "POST",
url: URL,
data: dataString,
cache: false,
beforeSend: function(){ $("#more"+ID).html('<img src="wall_icons/ajaxloader.gif" />'); },
success: function(html){
$("div.posts-holder").append(html).each(function(){
$('.posts-holder').masonry('reloadItems');
});
$("#more"+ID).remove();
}
});
}
else
{
$("#more").html('The End');// no results
}
return false;
});
this code working when clicking showmore button $('.posts-holder').masonry('reloadItems'); but collecting new posts in one place. But when I change the width of the page everything is improving.
I think that you can use $container.masonry(); after adding your elements, like this :
$("div.posts-holder").append(html).each(function(){
$('.posts-holder').masonry('reloadItems');
});
$container.masonry();
You can see it working here.
Hope that can help.
you have to use the appended method of masonry ... otherwise how would it know that you have added any new element.
Adding the elements simply wont align them as masonry doesnt have any event listner for new element added.
var el = $('<div class="kesif-gonderi-alani" style="height:300px;"></div>')
$container.masonry().append( el ).masonry( 'appended',el );
Hers is small demo on codepen http://codepen.io/knaman2609/pen/xbJMRY
Click on the button to append elements dynamically
http://masonry.desandro.com/methods.html

How can I keep scoll position on dynamic refresh div?

I'm searching a few hours ago for this, I can't finr anywhere.
I use simple Jquery script to refresh a div. I want to see my PHP output in that div.
$script = "
<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js\"></script>
<script type=\"text/javascript\">// <![CDATA[
$(document).ready(function() {
$.ajaxSetup({ cache: false }); // This part addresses an IE bug. without it, IE will only load the first number and will never refresh
setInterval(function() {
$('#uziRefresh').load('http://mypage/refresh.php?a_a=".$kinek[1]."');
}, 6000); // the \"3000\" here refers to the time to refresh the div. it is in milliseconds.
});
// ]]></script>
";
My problem is. When it refreshing it go to top position of div scroll. I would like to keep the current position, becouse my users my would like to read all content of the div. I would like to make a simple chat application. But it's bad cos always go to top.
How can I solve this? Anyone has a solution?
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajaxSetup({
cache: false
});
setInterval(function() {
var div = document.getElementById("uzidoboz").scrollTop;
$('#uziRefresh').load('/modulok/belso_levelezes/refresh.php?a_a=<?php print($kinek[1])?>', function(){
$("div.uzidoboz").scrollTop(div);
})
}, 6000);
});
</script>
This is my full solution. I'm sorry, I missed some div names, but with correct names the last solution not yet worked. This work fine. First I get the current scrolltop, reload the div, and set the scrolltop.
It runs in every 6000 millisecond. It's simple now and work. I have my divs. uzidoboz div have got overflow. My content is in that. But I load it all to the uziRefresh div...
Check this solution. I have removed your comments sorry!.
$(document).ready(function() {
$.ajaxSetup({
cache: false
});
var updateScrollPosition = function() {
var div = $('#uziRefresh');
div.scrollTop(div.height());
};
setInterval(function() {
$('#uziRefresh').load('http://mypage/refresh.php?a_a=".$kinek[1]."', updateScrollPosition);
}, 6000);
});
To be precise use this -
$script = "
<script type=\"text/javascript\">// <![CDATA[
$(document).ready(function() {
$.ajaxSetup({
cache: false
});
var updateScrollPosition = function() {
var div = $('#uziRefresh');
div.scrollTop(div.height());
};
setInterval(function() {
$('#uziRefresh').load('http://mypage/refresh.php?a_a=".$kinek[1]."',
updateScrollPosition);
}, 6000); // ]]>
";

jQuery, Shadowbox and AJAX

I would like to load some content using AJAX and Shadowbox
Basically I would like the user to goto a page in case javascript is off. So this is what I want to do :-
1) Cancel the click event i.e the User must not go to a different page.
2) Load content using ajax function in jQuery
3) Show the content inside a shadow box
My code works ok until loading content using ajax but the shadowbox is not displayed and the URL is gettin refreshed i guess, everything goes blank.
jQuery(document).ready(function($){
// rounded corners
$('img').addClass('corner iradius16');
DD_roundies.addRule('#nav li a',4,true);
DD_roundies.addRule('.grid',6,true);
$('h2 a').bind('click', function() {
var id = $(this).attr('id');
$.ajax({
url: "/ajax-post.php?p="+id,
success: function(data){
Shadowbox.open({
content: data,
player: "html",
height: 350,
width: 350
});
}
});
return false;
});
UPDATE 1
tried this code, and as soon as the shadowbox loads, the document gets reloaded and white.
Shadowbox.init({
skipSetup: true,
players: ["html"]
});
// LOAD
jQuery(document).ready(function($){
// rounded corners
$('img').addClass('corner iradius16');
DD_roundies.addRule('#nav li a',4,true);
DD_roundies.addRule('.grid',6,true);
$('.post h2 a').bind('click', function() {
var id = $(this).attr('id');
$.ajax({
url: "<?php bloginfo( 'template_directory'); ?>/ajax-post.php?p="+id,
success: function(data){
show_box(data);
}
});
return false;
});
});
//shadowbox
function show_box(html) {
Shadowbox.open({
content: html,
player: "html",
height: 350,
width: 350
});
}
UPDATE 2
Okay got the prbolem, the html that I am getting via ajax has some javascript in it and that is the reason for the page reload.
Why is this happening ? Any ideas ?
Since you're not getting any JavaScript errors try debugging by breaking it down:
Ensure that the binding to and overriding of the click event is functioning properly:
$('h2 a').bind('click', function() {
alert('click even fired');
return false;
});
If that works, check the data that your ajax request is returning:
$('h2 a').bind('click', function() {
var id = $(this).attr('id');
$.ajax({
url: "ajax-post.php?p="+id,
success: function(data){
alert(data);
}
});
return false;
});
The code looks like it should work, so I'm guessing there's either something wrong elsewhere (in which case the first test will likely fail) or you're getting some really odd data returned.
Need to run
Shadowbox.setup('h2 a');
This will reinitialise and bind it to any ajax loaded content

Categories