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
Related
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.
I need a preloader in JS for images. The images are fetched by a PHP script (to avoid opening the file structure to the user) and set as the attribute of the img tag. After the preload we wait for a event bound as an event listener to get fired (kind of like a slideshow).
var preloadImage = $('<img />').attr('src', 'getimage.php');
preloadImage.onLoad = function() {console.log('finished')}
The problem is, that of course onLoad does not work as it deals with the image being processed in the JS, while in this case we are waiting for the PHP to finish getting the image. The php script is just like this
<?php
header("Content-type: image/png");
readfile('image.png');
?>
Anyone has an idea how in this case i can make the JS wait till the php has finished loading?
As DaveRandom answered the question perfectly in the discussion above, here is the final code. preloadImage is a jQuery object which means that one needs to pass the .load() function.
var preloadImage = $('<img />').attr('src', 'getimage.php').load(function() {console.log('finished')})
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
I'm using jQuery address to enable loading specific content from other pages
and to change the URL in the address bar.
I'm working on a little Social Network alike website, so I'm reading out the IDs
of the posts table of my MySQL database via PHP. I want to use the possibilities of jQuery and AJAX to read everything out dynamically.
I found out, that I have to use live() (which turned out to be old), delegate() (which
also turned out to be old in 1.7.1) or on() (which turns out to be the best possibility
to make events work inside of dynamically loaded content via jQuery + AJAX).
I also read somewhere, that I can't use load() or get() to load new content from another
page inside of an already loaded content, because it doesn't "bubble" (I don't even know
what that means).
What do I have to do to load new content within an AJAX loaded page?
Here's a snippet I tried to work with (included on the loaded page):
<?php
if(exist('`posts`')) {
$load = mysql_query('SELECT `id` FROM `posts` ORDER BY `id` DESC LIMIT 10');
while($row = mysql_fetch_object($load)) {
?>
<script type="text/javascript">
$('body').on('body', 'load', function() {
$.get('getpost.php', { pid: <?= $row->id ?> }, function (data) {
$('#posts').html($('#post_<?= $row->id ?>', data).html()).show();
});
$('#posts').off('load');
});
</script>
<?php
}
}
else {
?>
<div align="center">No posts yet.</div>
<?php
}
?>
getpost.php is my file from which I can get the div_$row->id so that it appears on the start page.
PLUS (Just adding for your knowledge) I want the content to load the content without
a mouseover, click or blur event.
Thanks.
You want to use ".live()" if you want a particular event mapping to be applied dynamically to any new DOM elements which match its selector. Alternatively, you can attach the behavior to each chunk of content loaded.
Write and develop your ajax load independently of your DB lookup to make things simpler. The following snippet triggers another ajax call after each element loads.
<?php
$id = 'div'.mt_rand();
$counter = isset($_REQUEST['counter']) ? $_REQUEST['counter'] : 0;
$next = $counter + 1;
echo <<<END
<div id="{$id}">{$counter}
<script>
$(function() {
$.ajax('/url?counter={$next}', function(html) {
$(html).appendTo($('#{$id}').parent()); // or whatever your favorite method is for adding a sibling
});
});
</script>
</div>
END;
?>
Am I the only one who thinks that this approach is completely wrong? You're making an ajax request for each post, this could end up in making way too much requests, heavily slowing down the loading time. I can't see any reason why you don't want to directly write the posts' HTML inside the PHP while loop.
I am using the following script to display big images on mouse over the small images (example photo attached in the last). I want to show the 'loading' image (like this) while the big image is being downloaded from the server. How can this be achieved?
Note: I have asked a similar question here but I was not successful in applying the append function to the following code. Please help.
<script type="text/javascript">
function showIt(imgsrc)
{
var holder = document.getElementById('imageshow');
var newpic= new Image();
newpic.src=imgsrc;
holder.src=imgsrc;
holder.width = newpic.width;
holder.height=newpic.height;
}
</script>
<body>
/***on hover, xyz.jpg will be replaced by bigA.jpg and so on***/
<img src="smallA.jpg" onMouseOver="showIt('bigA.jpg')"/>
<img src="smallB.jpg" onMouseOver="showIt('bigB.jpg')"/>
<img src="xyz.jpg" id="imageshow" />
</body>
Images have a load event. As long as you set the load handler before the image.src is set, you should get notified when the image has successfully loaded or encounters some kind of error in loading. I do that very thing in a slideshow that I wrote so I know when the next image is ready for display and I display a wait cursor (animated gif like you're wanting) if the image has been delayed more than one second beyond it's appointed display time so the user knows what's going on.
In general, you can do something like this:
function loadImage(url, successHandler, errorHandler) {
var myImg = new Image();
myImg.onload = myLoadHandler; // universally supported
myImg.onabort = myErrorHandler; // only supported in some browsers, but no harm in listening for it
myImg.onerror = myErrorHandler;
myImg.src = url;
function myLoadHandler() {
successHandler(myImg, url);
}
function myErrorHandler() {
if (errorHandler) {
errorHandler(url);
}
}
}
Using code like this, you can display the wait cursor when you initiate the image load and hide it when the successHandler gets called.
If there were any other listeners to these events, then you should use addEventListener or attachEvent instead of onload, onabort, onerror, but if there's only one listener, you can go either way.
If the desired images are known in advance, then it's sometimes a better user experience (less waiting) to preload images that may be used later. This gets them into the browser's memory cache so they will appear instantly when needed. One can preload images either in HTML or in JS. In HTML, just insert tags into the web page for all the desired images (but hide them with CSS). In JS, just create an image array and create the image objects:
// image URLs to preload
var preloadImageURLs = [
"http://photos.smugmug.com/935492456_5tur7-M.jpg",
"http://photos.smugmug.com/835492456_968nf-M.jpg",
"http://photos.smugmug.com/735492456_3kg86-M.jpg",
];
var preloads = []; // storage for preloaded images
function preloadImages() {
var img, i;
for (i = 0; i < preloadImageURLs.length; i++) {
img = new Image();
img.src = preloadImageURLs[i];
preloads.push(img);
}
}
This will cause all the images in the preloadImageURLs array to be preloaded and available instantly later on in the life of the web page, thus preventing any user delays while waiting for images to be loaded. Obviously, there's a short amount of time for the preloaded images to actually get loaded, but for smallish images that usually happens before the user interacts with the web page so it makes for a faster feel to dynamic parts of the web page that use images.
<img id=access src=loading.gif>
<script>
window.onload=function(){
document.getElementById('access').src='access.jpg';
}
</script>
Hope this helps.