Load html with ajax, but hide content until loaded - php

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

Related

How to show loading animations or progress bars when retrieve data from database?

I retrieve about 15,000 rows from my database every time I visit this page.
The page might take about 8-10 seconds to finish load everything - I currently, use DataTable.
I think it would be nice to show user any kind of loading feedback during that time.
I want to create my own loading animations, and chose my own color, style, and size.
I'm not if I use any Ajax call.
I am just retrieving a lot of data out of my database.
What is the most efficient way to show loading animation while retrieving data from database ?
To begin with, the most simple solution is to use ajax call to retrieve the table rows populated by php.
JSFiddle
SIMPLE:
main.html / main.php
/*This makes the timeout variable global so all functions can access it.*/
var timeout;
/*This is an example function and can be disregarded
This function sets the loading div to a given string.*/
function loaded() {
$('#loading').html('The Ajax Call Data');
}
function startLoad() {
/*This is the loading gif, It will popup as soon as startLoad is called*/
$('#loading').html('<img src="http://rpg.drivethrustuff.com/shared_images/ajax-loader.gif"/>');
/*
This is an example of the ajax get method,
You would retrieve the html then use the results
to populate the container.
$.get('example.php', function (results) {
$('#loading').html(results);
});
*/
/*This is an example and can be disregarded
The clearTimeout makes sure you don't overload the timeout variable
with multiple timout sessions.*/
clearTimeout(timeout);
/*Set timeout delays a given function for given milliseconds*/
timeout = setTimeout(loaded, 1500);
}
/*This binds a click event to the refresh button*/
$('#start_call').click(startLoad);
/*This starts the load on page load, so you don't have to click the button*/
startLoad();
img {
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='start_call'>Refresh</button>
<div id='loading'></div>
An example of the php would look something like this
example.php
/*Database call to get list*/
foreach($list as $li){
echo "<tr><td>$li[var1]</td><td>$li[var2]</td></tr>";
}
ADVANCED:
A more advanced way to load your content is to use webworkers and multiple database calls segregated into small chunks.
You would set up web-workers to do small 100 row results and use LIMIT in your sql statements to page the results into small chunks. Then you can page through the first 100 results while the other results are loading.
This process is more difficult and takes longer to implement, but leads to seamless and quick loading.
EDIT:
If you want to change the loading animation just change the URL. and if you want the URL to be loaded on page load put it in the div itself.
/*This will make the img load on page load rather than DOM execution.*/
<div id='loading'>
<img src="http://rpg.drivethrustuff.com/shared_images/ajax-loader.gif"/>
</div>
The Image doesn't have to be an image. It can be any loading icon you want. A gif was quick and dirty. You could use something like font-awesome spinner
data.php to check out the DB and build the table's HTML
function getData(){
//div contains the loader
$('#loader').show();
$.get('clients/data.php', function(data) {
//
$('#content').html(data);
//hide the loader
$('#loader').hide();
//build DataTable
$('#content table').dataTable();
});
}
getData();
This depends on what language you use, but the fundamentals are the same. You load the page with just the animation while the query completes, and then replace the animation with the content.
In jQuery this probably means linking the animation in plain HTML, then separately calling the database with AJAX. When you get the result, you can use jQuery append to target the content area, and write into that in real time.
I include PHP since you say that you are not using AJAX, but in PHP the structure is the same: You would need to link the image, flush the page so that it displays, and then execute your query. Cover the animation with negative CSS margin-top on the search results, and Bob is your uncle.
Your question :
"I want to create my own loading animations, and chose my own color, style, and size."
You should visit http://www.ajaxload.info/ there you can chose,customize and download loading gif really fast.

jQuery scrollbar plugin not working on Ajax loaded content

The problem is this:
I have a simple, two fields form which I submit with Ajax.
Upon completion I reload two div's to reflect the changes.
Everything is working perfect except a jQuery plugin. It's a simple plugin that can be called with simple
function(){
$('.myDiv').scrollbars();
}
It's simple and easy to use, but it doesn't work on Ajax loaded content. Here is the code I use to post form and reload div's:
$(function() {
$('#fotocoment').on('submit', function(e) {
$.post('submitfotocoment.php', $(this).serialize(), function (data) {
$(".coment").load("fotocomajax.php");
}).error(function() {
});
e.preventDefault();
});
});
I've tried creating a function and calling it in Ajax succes:, but no luck. Can anyone show me how to make it work ? How can that simple plugin can be reloaded or reinitialized or, maybe, refreshed. I've studied a lot of jQuery's functions, including ajaxStop, ajaxComplete ... nothing seems to be working or I'm doing something wrong here.
If you're loading elements dynamically after DOM Document is already loaded (like through AJAX in your case) simple binding .scrollbars() to element won't work, even in $(document).ready() - you need to use "live" event(s) - that way jQuery will "catch" dynamically added content:
$(selector).live(events, data, handler); // jQuery 1.3+
$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+
$(document).on(events, selector, data, handler); // jQuery 1.7+
Source: jQuery Site
Even if I am totally against using such plugins, which tries to replicate your browser's components, I'll try to give some hints.
I suppose you are using this scrollbars plugin. In this case you may want to reinitialize the scrollbars element, and there are many ways to do this. You could create the element again like in the following example
<div class="holder">
<div class="scrollme">
<img src="http://placekitten.com/g/400/300" />
</div>
</div>
.....
$('.scrollme').scrollbars();
...
fakedata = "<div class='scrollme'>Fake response from your server<br /><img src='http://placekitten.com/g/500/300' /></div>";
$.post('/echo/html/', function(response){
$('.holder').html(fakedata);
$('.scrollme').scrollbars();
});
If you want to update the contents of an already initialized widget instead, then things gets more complicated. Once your plugin initialize, it moves the content in some custom wrappers in order to do its 'magic', so make sure you update the correct element, then trigger the resize event on window, pray and hopefully your widget gets re-evaluated.
If it doesn't help, then try to come up with some more details about your HTML structure.
I want to thank everyone of you who took their time to answer me with this problem I have. However, the answer came to me after 4 days of struggle and "inventions" :), and it's not a JS or Jquery solution, but a simple logic in the file.
Originally, I call my functions and plugins at the beginning of the document in "head" tag, like any other programmer out here (there are exceptions also ).
Then my visitors open my blog read it and they want to post comments. But there are a lot of comments, and I don't want to scroll the entire page, or use the default scroll bars, simply because they're ugly and we don't have cross browser support to style that, just yet.
So I .post() the form with the comment, and simply reload the containing all of them. Naturally .scrollbars() plugin doesn't work. Here come the solution.
If I put this :
<script>$('.showcoment').scrollbars();</script>
in the beginning of my loaded document (with load() ), will not work, because is not HTML and it's getting removed automatically. BUT !!! If i do this:
<div><script>$('.showcoment').scrollbars();</script></div>
at the same beginning of loaded document, MAGIC .... it works. The logic that got me there I found it in the basics of javascript. If your script is inside an HTML element, it will be parsed without any problem.
Thank you all again, and I hope my experience will help others.
If I understand you correctly, try this:
var scrollelement = $('.myDiv').scrollbars();
var api = scrollelement.data('jsp');
$(function () {
$('#fotocoment').on('submit', function (e) {
$.post('submitfotocoment.php', $(this).serialize(), function (data) {
$(".coment").load("fotocomajax.php");
api.reinitialise();
}).error(function () {
});
e.preventDefault();
});
});
reinitialise - standart api function, updates scrolbars.

jQuery and Drupal behavior issue on document.ready

I have an odd problem in my jQuery code that loads in Drupal 7. I used the following instruction :
(function ($) {
Drupal.behaviors.exampleModule = {
attach: myPopUpFunction.....
})(jQuery);
On my mac browsers this codes loads after the document is loaded however on PC the popUp loads first and then the whole page loads.
Any idea?
Thank you,
not sure if your issue is browser specific, but my suggestion is that you could bind the myPopUpFunction with the window's load event, in that way only after the window's elements are all loaded the popup method would be triggered invoking the popup load
$(window).bind('load', function() {
// popup load goes here
});
this should serve the cause, but the popup would load after 'all' the elements including images which might not be desired.
Note: jQuery 1.7 onward suggests method .on() instead of bind.

How do I determine when an image has finished loading?

I have a block of php code that loads an image at random. I'm trying to determine when the image has loaded so I can perform some additional actions on it. Here is how I'm currently loading my image:
// Gets my image
$sql = "SELECT id FROM images WHERE user_id=$owner_user_id LIMIT 0,1";
$imgres = mysql_query($sql);
if ($imgres) {
$imgrow = mysql_fetch_array($imgres, MYSQL_ASSOC);
if (!empty($imgrow)) {
echo ('<image src="img.php?id=' . $imgrow['id'] . '" id="profile_img" style="visibility:hidden"/>');
}
}
One of the actions I need to do is get the width of the image. I'm getting the image like so:
alert("IMAGE WIDTH:"+$('#profile_img').width());
It currently returns 0 because it's being called prior to the image being loaded. I've tried adding this method call to my document.ready block but it still gets called prior to the image being loaded. Is there an easy way to determine when the image has loaded?
$(document).ready(function(){
$('#img_id').load(function() {
alert('image is loaded');
});
});
this will do the trick
you can bind a load event handler to your image with jquery:
http://api.jquery.com/load-event/
$("#profile_img").load(function(){
alert(("IMAGE WIDTH:"+$('#profile_img').width())
});
http://api.jquery.com/load-event/
This really has nothing to do with PHP; image loading is done client side, so you'll need to do it in the Javascript side of things. You'll be dealing with Javascript events - here's a primer:
http://www.quirksmode.org/js/introevents.html
Luckily, jQuery has a built-in function to bind to the event for you (even called load()!) which allows you to pass a callback to fire once that content is loaded.
Your best bet is to preload the image in JavaScript prior to the DOM loading at all:
<SCRIPT language="JavaScript">
preload_image = new Image(25,25);
preload_image.src="http://mydomain.com/image.gif";
</SCRIPT>
Do NOT use jQuery .load() to test when images are loaded. According to the jQuery docs:
•It doesn't work consistently nor [is it] 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

dynamic loading content containing javascript

I want to add a progress bar before my web page's content loads, so I thought of loading it dynamically via javascript. This content has embedded javascript in its html. I tried using jquery.load() which works perfectly besides the fact that it does not support the js that doesn''t work on the returned content
just to make it clear, what i'm doing is something like this to load all the content:
$("#contentid").html("progressBar.gif");
$("#contentid").load(script.php #content)
$("#contentid").show();
and inside the content returned from script.php there are js calls such as:
jquery.load (to crawl for data and displaying it when ready)
document.getElementById('some_div') (for chart api)
snippets that load widgets
I've been trying to work around with using jquery.ajax though not sure if\how its possible with it yet. would love for some input on that.should i be able to achieve that with it?
Any other idea that might show a progress bar till the script's content is loaded will be great. I'm trying to reduce changes in the code structure, since this long load happens only sometimes.
Thanks.
You may add a div with the progress bar, covering all the page, and remove it after the page is loaded, using:
$(window).load(function() {
$('#progressbar').remove();
});
JQuery's load method takes a callback function as an argument. That function will get called when the load is completed, so you can hide your progress bar at that point. Here is an example from their API docs:
$('#result').load('ajax/test.html', function() {
alert('Load was performed.');
});
In your case, it would be something like:
$("#contentid").load(script.php, function(){
$("#contentid").hide();
});

Categories