I'm pretty new to jQuery, AJAX, and web dev in general, so this is driving me crazy.
I've got an AJAX request that pulls in page content into the current one, and I'm trying to coerce jQuery into displaying it like so:
Fade out current content
Smoothly resize the div to the new content
Fade in new content
So far, I've got it written up something like this. I've changed it a round a bunch, so this might not be the closest I've gotten, but the same problem still persists.
$("#page-data").fadeOut(600).html(data);
$("#page-data").ready(function() {
var newHeight = $('#' + divname).height();
$("#page-data").animate({
height: newHeight,
}, 600, function() {
$("#page-data").fadeIn(100);
});
});
Where page data's got this simple style:
#page-data { position: relative; overflow: hidden; }
My problem is that $('#' + divname).height() doesn't account for images and other things that could occur in the div. I tried using .load() instead of .ready(), but then the callback isn't called at all.
Since there isn't any HTML included in the question, I'm assuming that you have your container <div id="pageData"> that holds another <div> (identified by divname), into which you are loading your dynamic content.
Firstly, $(..).ready() can only be used used on the document object, so using applying it to a <div> goes against jQuery's documentation.
The best way I can think to acheive your goal is to keep track of any images in the HTML that you have dynamically loaded via AJAX and monitor them until they have all been loaded. Then you can apply your logic for setting the height of your container <div>.
The problem is that if we apply a load event handler to an image that has already loaded, then it won't fire. Working out whether an image has been already loaded can be tricky, but the received wisdom seems to be to check the complete property (if it exists) or check whether the the height of the image is greater than 0:
function imageLoaded(img) {
if(typeof img.complete != 'undefined') {
return img.complete;
}
else {
return(img.height > 0);
}
}
Now we can take the following steps:
Fade out the <div> (e.g. #pageContent) that will contain your AJAX
content
Load the AJAX content
Search through the new content for all
images, count how many there are, add a load event handler to each
one, then cycle through each image checking if it's already loaded
and manually firing the load event if so.
In the load event we decrement the counter. When the counter reaches zero, then calculate the height of the container <div> and fade in the content
For example (see here for a working jsfiddle):
$pageData = $('#pageData');
$pageContent = $('#pageContent');
$pageData.height($pageData.height());
$pageContent.fadeOut(function() {
$pageContent.load('http://your.dynamic.content', contentLoaded);
});
function contentLoaded() {
var $loadables = $(this).find('img');
var loadableCount = $loadables.length;
// Attach onLoad event handlers to each image
$loadables.load(function() {
loadableCount--;
checkAllLoaded(loadableCount);
});
// Trigger the onLoad events manually for any images that have already loaded
$loadables.each(function() {
if(imageLoaded(this)) {
$(this).trigger('load');
}
});
}
function checkAllLoaded(loadCount) {
if (loadCount <= 0) {
$('#pageData').animate({
height: $('#pageContent').height()
}, 600, function() {
$('#pageContent').fadeIn();
});
}
}
Related
I've a gallery with a large image slider and a small grid of thumbnails working in php but I need a javascript function to swap and reuse this function to interactively load the new images and thumbnails. How would I pass the start parameter to a Jquery function to fill the image slider and the grid? Currently I'm writing a href to the document with the start parameter and in the document.load function I scrap this href und fire a getjson function to pull the records from my database?
Here is my Jquery, it looks for the first href in my menu li document subtree and use it as get parameter to pull the records from my database:
$j("#tx-gallery-pi1 #menu li").click(function() {
$j.getJSON($j(this).find('a').attr('href'), function(json) {
var container = $j('#tx-gallery-pi1 #container');
container.masonry();
$j.each(json, function(idx, ele) {
container.append($j("#brickTemplate").tmpl(ele).css({
"display": "block"
})).masonry('reload');
container.imagesLoaded(function() {
// bricks correct height
var brick = $j("#tx-gallery-pi1 #container .brick");
brick.each(function() {
var content = $j(this).find(">div");
var img = $j(this).find("img");
content.css({
height: img.attr("height")
});
});
});
});
});
return false; // don't follow the link!
});
}
when you create an HTML document with php, you can say
<script>
var startvar ='<?php echo($yourvariable); ?>';
</script>
and use it later on in the site.
You can update your output document using AJAX.
you should split that php in different actions on your controller (like get_thumbnails and get_image with the html code for each part) and using jQuery you can do "$(thumbnails_container).load('/get_thumbnails.php')", it would be easier to answer if you put at least the relevant code
check the jQuery's load method's docs if you need post or get parameters
I'm using jQuery to load content dynamically when the user clicks a link. The content is just a bunch of images that are then set to display in a slideshow of sorts. My problem is, I can't seem to figure out a way to show the loaded content only AFTER the images have fully loaded. I've tried several different solutions and all of them seem to either break the script or just not work the way I want. Here's the code I'm using now:
$(document).ready(function() {
$("a#item").click( function() {
var projectName = $(this).attr('class');
$("div.slideshow").css("display", "block");
$("div.slideshow").load(projectName+".php", function() {
var slideshow = new Array();
$("div.slideshow img").each(function() {
slideshow.push($(this));
});
startSlideshow(slideshow.shift());
function startSlideshow(image) {
image.delay(400).fadeIn(150, function() {
if(slideshow.length > 0) {startSlideshow(slideshow.shift());}
else { $("div.slideshow").delay(400).fadeOut(200, function() {$("div.slideshow img").css("display", "none")}); }
});
}
});
return false;
});
});
You can also see the full demo site here: http://publicprofileproject.com/
Any input would be greatly appreciated!
You could create an array of image objects in your JavaScript, loading each image into an element of the array. Attach an event handler to the onLoad event of the images.
In the event handler, increment a count of loaded images. When your counter reaches the length of your array, the browser will have all of the images. This is the point at which you can show your slideshow.
If you do this in your page load, it will have the added advantage of pre-loading the images ready for when the user clicks your link.
I believe this question has already been answered here.
The general idea is that you specify a load event handler to display it prior to specifying the source attribute.
Alternatively, if your projects+".php" file is specifying the images in ready-made, html mark-up, then you should be able to capture the load event of the images in the file you are loading. Add the following pseudocode into your file that is being loaded.
$("img").load(function() {
// show the div on the page it is getting loaded into
alert("images should be loaded now");
});
You might be able to place it in your original code segment and potentially bind it using the live / on binding events. ex: $("img").on("load", function() {...
From the load documentation:
The load event is sent to an element when it and all sub-elements have been completely loaded. This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object.
Edit: Interesting discouragement for doing what it looks like you're doing:
Caveats of the load event when used with images
A common challenge developers attempt to solve using the .load() shortcut is to execute a function when an image (or collection of images) have completely loaded. There are several known caveats with this that should be noted. These are:
It doesn't work consistently nor reliably cross-browser
It doesn't fire correctly in WebKit if the image src is set to the same src as before
It doesn't correctly bubble up the DOM tree
Can cease to fire for images that already live in the browser's cache
So I have I this javascript that loads into a div the contents of my php (which gets data from a mysql database). When a different button is clicked, it calls the eat.php file again, with the new data to retrieve from MySQL and again loads the new data into the div.
<script type="text/javascript">
$(function() {
$("a[name=eat]").click(function() {
$("div.nav a[name=eat]").css({"background-color":"#666966","color":"#fff"});
$(".user-main").load("eat.php");
});
$("a[name=analyze]").click(function() {
$(".user-main").load("eat.php",{ name: "John", time: "2pm" });
});
});
</script>
And that is ok and everything. My question is how can I make this "slide" into the new div, like it's being scrolled horizontally? I am having no luck with the animate feature in jQuery, and would prefer not to use any frameworks. Also, is the correct way to check for a jQuery post by doing:
if (isset($_POST['name']))
in my eat.php file?
I am not quite sure what you are asking.
If you want to ensure the data you have just added is scrolled into view, then you can use code like this
if (document.all) {
document.body.scrollIntoView(false);
} else {
document.body.insertAdjacentHTML('beforeEnd','<a name="' + a + '"><\/a>');
window.location.hash = '#'+a;
}
The trick with insertAdjacentHTML is inserting a label into the screen and then telling the browser to jump to it. The label is the contents of a javascript variable which must be different each time the code is run.
If you wish to slide a whole division into view, then you will have to use a timer. Set up the div so the over-flow is hidden and it is positioned off screen, using position relative and large top or left/right values. Then, each time the timer goes off, decrease the offset towards zero.
If the timer goes off every 50ms and you move only a few pixels, you will get 20fps and it will appear quite smooth.
EDIT: This question was initially too general, I think. So What I really need is a very good tutorial on how to implement the Load More function on Safari for iPhone just like the Twitter website(mobile.twitter.com) does. Just a wordpress plugin won't really help. But if the plugin is well explained, like if it is wptouch, home(that also has this function) that can also do.
I know that it doesn't really matter that it is being displayed on a mobile device, but the point I am stressing is that if such a function is well explained, then it will be up to me to know how to customize it to suit me.
I am using a javascript function to load entries that come from the database dynamically, so that content opens in the same page (like with twitter(tweets feed) and facebook(news feed)).
The php/html version(That opens a page in a new tab) is
echo 'Load more entries› ';
The javascript/ajax version:
<div id="call_hv<?php echo md5($_SERVER['REQUEST_URI']); ?>" class="ajax-load-more">
<img id="spinner<?php echo md5($_SERVER['REQUEST_URI']); ?>" class="spin" src="<?php bloginfo('template_directory'); ?>/images/main-ajax-loader.gif" style="display:none" alt="" />
<a class="ajax" href="javascript:$ajax_hv('#spinner<?php echo md5($_SERVER['REQUEST_URI']); ?>').fadeIn(200);
$ajax_hv('#ajaxentries_hv<?php echo md5($_SERVER['REQUEST_URI']); ?>').load('form='<? echo $form_id; ?>&page=<?php echo $page+1;?>', {},
function(){ $ajax_hv('#call_hv<?php echo md5($_SERVER['REQUEST_URI']); ?>').fadeOut();})">Load more entries...
</a>
The basic idea is to listen to scroll events, and implement paging on the server side.
A scroll event is fired whenever the document or a contained HTML element scrolls. I'll use this sketch for reference keeping the following things in mind:
Let's say the height of the browser window is 800px, and the initial height of the content is 2500px. The threshold for loading AJAX content is when the user scrolls to the bottom 100px of our content (after the first 2400px).
We will need to keep track of the following 2 items:
Items/Pages loaded so far.
How far are we from the bottom of
the page.
The code references are in MooTools, but the concept is the same. Converting it to jQuery is a trivial task once you understand it.
var maxPage = 1;
var threshold = 100;
We need to know whenever the page scrolls, so add a handler for scroll events. Find the scroll distance to the bottom of the page. If it's less than the defined threshold (100px), then fire off an AJAX request loading the next page. When the response comes (if successful), append it to the page and increment maxPage number.
Another thing to keep in mind is to only fire an AJAX request if content is not already being loaded. Have a flag that indicates whether the page request is still pending.
var isLoading = false;
window.addEvent('scroll', function() {
// the height of the entire content (including overflow)
var contentHeight = window.getScrollSize().y;
// current scroll is height of content that's above the viewport plus
// height of the viewport.
var contentScrolled = window.getScroll().y + window.getSize().y;
var distanceToBottom = contentHeight - contentScrolled;
var closeToBottomOfPage = distanceToBottom < threshold;
var shouldLoadMoreContent = !isLoading && closeToBottomOfPage;
if(shouldLoadMoreContent) {
// create an ajax request
var request = new Request({
url: 'http://www.example.com/more',
onSuccess: function(responseText) {
$('page').append(responseText);
maxPage++;
},
onRequest: function() {
isLoading = true;
},
onComplete: function() {
isLoading = false;
}
});
// fire off ajax request with the page # as a querystring param
request.send({page: maxPage});
}
}
Commonly called an Infinite scroll. There are plugins for jQuery and Wordpress:
http://www.infinite-scroll.com/
I have no experience with jquery or javascript for that matter.
I am trying to implement this technique to respond to users for errors or messages in general.
lights-out-dimmingcovering-background-content-with-jquery
This method uses the onclick event and that's not what im after, I have tried to replace .onclick with .load but that doesn't seem to work. I'm after a quick fix as I really don't have the time to learn jquery or its event handlers.
The goal is to catch any errors or message's and once these are called the alert box is called without any further actions such as .onclick.
How my code would look:
{PHP}
$forms = new forms();
if(count($forms->showErrors) > 0 // or == true)
{
foreach($forms->showErrors as $error)
{
print('<p class="alert">'.htmlspecialchars($error, ENT_QUOTES).'</p>');
}
}
Edit:
ALL FIXED, thanks!
You're on the right track with ".load" but you want to bind this functionality to the "ready" event of the page (when the DOM is complete; you don't need to wait for the load event), so here's what you need to change - assuming you're using the code sample on the Lights Out page:
$(document).ready(function(){
//Adjust height of overlay to fill screen when page loads
$("#fuzz").css("height", $(document).height());
//When the link that triggers the message is clicked fade in overlay/msgbox
//$(".alert").click(function(){
// $("#fuzz").fadeIn();
// return false;
//});
// INSTEAD: If any errors are present in the page, fade in the layer:
if ( $("p.alert").length ) {
$("#fuzz").fadeIn();
}
// end of change
//When the message box is closed, fade out
$(".close").click(function(){
$("#fuzz").fadeOut();
return false;
});
});
//Adjust height of overlay to fill screen when browser gets resized
$(window).bind("resize", function(){
$("#fuzz").css("height", $(window).height());
});
Be sure to include the HTML and CSS for the layer, too.