make sure an image is loaded while dynamically changing jquery - javascript

I'm changing the image src of an image node.
I want to be able to make sure that it's changed before executing somecode. How would i do that?
right now i have
function changePic(imgNode, newPic, desc){
var descNode = $("#description");
$(imgnode).fadeTo(500, 0, function(){
$(imgnode).attr("src", newPic);
$(imgnode).attr("alt", desc)
descNode.text(desc);
$(imgnode).fadeTo(500, 1);
});
}
Works great if the server's fast/ a local server. Works terribly if the server's slow, where the image will fade back in before changing...
any idea?
Edit: I'm loading the image when changePic is called. Any better ways to do it?
More: Also why is it not a good idea to put the last line,
$(imgnode).fadeTo(500, 1);
, outside of the callback function?

Preload the image, but to be sure it's completely loaded, use the .load() event.
Quote:
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.
And don't miss this line:
It is possible that the load event
will not be triggered if the image is
loaded from the browser cache. To
account for this possibility, we can
use a special load event that fires
immediately if the image is ready.
event.special.load is currently
available as a plugin.
I put together an example of how I think you want it to work. I switch between three images I found through Google Images. I bind the load event before I change the src of the image to be sure it's triggered.
http://jsfiddle.net/xdjjR/1/

I guess, you can preload image in hidden elements, so that it's loaded with other html. When the source changed such image should be shown immediately.

Use the callback param
doc
ex from doc:
$('#clickme').click(function() {
$('#book').fadeOut('slow', function() {
// Animation complete.
});
});

Related

Remove background url but only AFTER an image has fully loaded

I am loading an image from the client side using createObjectURL. Sometimes, the image is big, so I wanted to put a "loading" animated gif in there.
I have a container div (fileDisplay) and an img (imgDisplay).
fileDisplay has the background set to the animated gif. So, as imgDisplay is loading a big file, you see the loading gif. When imgDisplay is done loading, it covers the gif. So, its still there, but you dont see. I figured that should be fine. All is well--as long as the img is a square, which distorts the img proportions.
But, if the image loaded into imgDisplay is resized with correct proportions and not square (fileDisplay dimensions are 45x45 pixles) you still see the gif in the background.
So what I need is to be able to turn off the animated gif (background url=none on fileDisplay), or cover it with another div, or something. But only when the image has fully loaded.
I can see by now, after trying everything I can think of, that there is no way to change backgrounds, turn divs on/off, etc and do this. It seems everything is processed and then the final results are all painted at once as opposed to incrementally as if it were, say, a VB app.
Can anyone help me with working out how to do this--I'm assuming it CAN be done. And I think the solution is "promise." I have looked for samples, read what I can find, but just can't seem to grasp it.
The "uploadButton on change" event fires this code:
imgSrc = window.URL.createObjectURL(this.files[0]);
//document.getElementById("imgDisplay" + justNumber).src = imgSrc;
getImgSize(imgSrc, useImgSize);
Where the commented line just displays the image as a 45x45. But the getImgSize function calculates the size and displays the image resized--which is when the problem occurs. Just try to load an image that is not square and you will see the issue.
A complete fiddle is here: https://jsfiddle.net/msith718/xfuv79b3/334/
So to do this you want to remove the gif/img element from the parent div when you load the new image into the div. Which you would do with the element.removeChild() function.
//Put this code as soon as you want to remove the loading gif
//This gets the node or the element you want to remove
var node = document.getElementById("gif");
//This removes the node from the parent div
document.getElementById("parentDiv").removeChild(node);
Here is one way of solving this problem https://jsfiddle.net/xfuv79b3/353/. Because you are wanting to change something after the image has loaded we need to add the code somewhere after the onload event has been called. I chose to pass in an id to my imgLoader that gets passed on to the callback that processes the image once loaded. Then finally use that id to modify the background of the div once the img element has loaded the new image. What you ne
getImgSize(imgSrc, useImgSize, justNumber);
//...
img.onload = function() {
fn({
width: img.width,
height: img.height
},id);
}
//...
document.getElementById("imgDisplay" + id).onload=function(){
document.getElementById('fileDisplay'+ id).style.background='none';
}
//Also to reset the background if upload is canceled
document.getElementById("fileDisplay" + justNumber).style.background = '';
Extra Note
From your reference to vb and painted I'm guessing your background is more geared towards a main loop that handles all of the interactions and holds all the data or state of your application. Javascript is very different from this in that user interactions happen through events which are asynchronous. This means data has to be explicitly passed around if need inside a certain callback.
Think about it like this. Your program starts in a resting state, but is listening for events that signal some change has happened. If an event happens (such as a user clicks a button) your program calls an event handler. This happens asynchronously meaning two things. One the only data available to it is the data passed into the handler and the data available from its parent scope. And two it means any subsequent actions or data processing have to be called from that event handler. So each event handler must perform all the actions needed and any state change updates to the program before returning to the resting state. Then your program waits for the next event.
This is very simplified (e.g. multiple events can be fired at the same time) and hopefully helpful, but once you get the hang of it javascript makes a whole lot more sense. I'd suggest reading up on event driven programming with javascript since I'm sure there are much better tutorials and explanations out there, but hopefully this gets you headed in the right direction.

get $.height() of an Element with Images in it when Image maybe not loaded yet

I insert some HTML code after a Ajax Call and in the Ajax-Callback I need the height of the added Div.
The problem is, in the HTML from the Ajax Call are elements like Images and other elements that have to be laoded first.
I did a simple example of the problem in jsfiddle: http://jsfiddle.net/qbwd663s/3/
As you can see when I add the code the console says 36, but if you click the div it says 242 (cause the image is loaded). Sometimes it works too if the image is allready in the cache, to test it reload the page with cleared cache.
What I need is something like $(document).ready() but only the elements that got called by ajax. Anyone have an idea how I could do that?
$("div *").one("load", function() {
alert($("div").height());
});
Fiddle: http://jsfiddle.net/aravi_vel/qbwd663s/6/
Use the load function as suggested by Harry
This function will handle the other kind of elements that you have listed (iframe etc.)

Intercepting HTTP event using JQuery

I have this JQuery code working however I need to know whether how to actually get the URL executed from the tags selected.
$("link, script, style, a, img").each(function () {
$(this).load(function () {
// get the URL and log it
console.log("Intercepted HTTP Event");
});
});
First thing I need to do it to get the actual URL during the load.
Next thing I may need to do is to actually catch before the load event happens, I mean before an image or link is loaded for example. Also, I need to modify the URL of the event that will be executed, for example, img tag has src="/somewhere/image.png" I mean, this will cause a GET /somewhere/image.png I may need to change it to GET/otherplace/image.png
Any ideas how to achive any of these?
$(this).load() will fire after the contents of the element have been loaded. So you may be able to grab the URL by doing $(this).attr("src") or $(this).attr("href"), but it's already too late to stop the HTTP requests from going out.
AFAIK, with modern browsers, there's no way for JavaScript to prevent assets from being loaded in the first place. At best, you may be able to change images and stylesheets after the page has been loaded, by changing the src attributes. If you do this, make sure that $(this).load() doesn't go into an infinite loop. (<a> links are less of a problem. Nothing is loaded, so just change the href attribute.)
.attr('src')
http://api.jquery.com/attr/
One way to approach this problem would be to have some dummy links/hidden controls with the source of your external resource and once the page loads you go through all such controls and then create the respective html elements, update the src attribute and then append it to the dom.
Dummy Controls:
<input type="hidden" source="/my/source/a.jpg" nodeType="img" class="specialControls"/>
<input type="hidden" source="/my/source/1.js" nodeType="script" class="specialControls" />
and the javascript
$(document).ready(function()
{
$(".specialControls").each(function(){
var elementType=$(this).attr("nodeType");
$('<'+elementType+'/>').attr('src', $(this).attr("source"))
.insertAfter($(this))
});
});
Hope this helps.

Check if iFrame is loaded. ONE time. Jquery

I know there is many of possiblites when it comes to check if an iFrame content has been loaded. Although, is there anyway to limit it?
Example, if I have an iframe, and I need to check if everything has loaded, I can use the load() function. Although, if I click a NEW link inside the iframe, it will run the load() function again.
What I wish to know, is there any way to do, so jquery only checks the FIRST time the iFrame content has been loaded?
I have tried everything, nothing works.
Use jquery .one, it does the unbind work for you.
$('#iframe').one('load', function() {
});
Example fiddle.
You can unset the load callback again once it gets called.
$('#iframe').load(function() {
// do things which are awesome
$('#iframe').unbind('load');
});

Accessing from the page in LowerFrame to the page in UpperFrame causes undefined error!

My website consists of two frames, let's say upperFrame and lowerFrame.
On the document ready of the page in lowerFrame, it access one of textbox located on the page of upperFrame.
Sometimes, since the upperFrame do NOT complete its loading, lowerFrame get the undefined while it access the upperFrame.
Let me know if there are Any solutions/checking to prevent this problem?
How about updating 2 vars in the parent of both frames: topReady and bottomReady. At the top and at the lower frames you set them to call a function that checks if both of them are true. If not it sets the appropriate var to true and once the 2nd frame will be calling the function it will trigger whatever action you want to.
Edit:
Another option is to try and use
$(window.parent.upperFrame).ready(function(){
alert('upperFrame loaded')
});
try jQuery .load() function
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.
Here is the sample code
Edited:
put code below in document ready of lower iframe.
$(function(){
$('#UpperIframeID', window.parent.document).load(function(){
var valueOFTextbox = (this).contents().find("#textboxID").val();
});
});
</script>
If it doesn't work in IE then put conditional statement and for IE use .ready() function.

Categories

Resources