I am getting an inconsistent error with my script. Often times everything works fine, however, every now and then I am getting the following error: ReferenceError: fadeIn is not defined
Here is the relevant code:
In the <head>
<script type="text/javascript" charset="utf-8">
window.fadeIn = function(obj) {
var item = $(obj).parent();
item.fadeIn(1000);
}
</script>
In the <body>
<div class="item" style="display:none"><img onload="fadeIn(this)" src="/uploads/thumbs/{{image.url}}"><br>{{ image.description }}</div>
Again, The images are loading and fading in most of the time but every now and then I get the error and the images do not fade in.
Is there a better way to approach this? Or just something I'm missing?
You need to make sure your code is loaded after the DOM is ready.
window.onload = function(){
var fadeIn = function(obj) {
var item = $(obj).parent();
item.fadeIn(1000);
};
};
... that's a partial fix, but not really, because in all likelihood, your <img/> tags with the onload hardcoded into them is going to try to fire that method before it's available.
Since you're using jQuery anyhow, you should look at something like this:
$(function() {
$(".item img").load(function(){
$(this).fadeIn(1000);
});
});
and get rid of the hardcoded onload from your img tags.
It should be noted, also, that there are caveats listed on the .load() API page:
From the docs (http://api.jquery.com/load-event/):
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
A better solution might be to hide the images with CSS, then after the load event is fired, fade them in.
(Even better than that might be to let browser behavior be, as your results may be mixed, and users seeing a blank page might instead hit the reload button thinking their browser glitched, before your animations are complete. ... just a friendly warning that these kinds of DOM manipulations can sometimes have unintended side-effects on user behavior!)
You can try defining the Handler directly in the Script instead of assigning it in HTML..
Javascript
<script type="text/javascript" charset="utf-8">
$(function() {
$('img').load(function() {
var item = $(this).parent();
item.fadeIn(1000);
});
});
</script>
HTML
<div class="item" style="display:none">
<img onload="fadeIn(this)" src="/uploads/thumbs/{{image.url}}">
<br>{{ image.description }}</div>
You're missing a document ready, so jQuery is'nt loaded, and the fadeIn function is'nt defined. Even if the image is loaded, there is no guarantee that jQuery is loaded aswell.
You're also actually calling your function fadeIn, while jQuery already has a function called fadeIn, and even though they have a different namespace it does seem like a bad idea to me.
nPlease ensure you have correct link to JQuery javascript file. You can use Google's hosted library for an example or create your own copy of this .js file:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
min.js file can be found at download section of JQuery official website. Save it and place into the website folder. And link it like:
<script src="/js_folder/jquery-1.8.2.min.js"></script>
Another option with Jquery:
<div class="item" style="display:none">
<a href="http://docs.jquery.com/">
<img src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif">
</a>
<p>image name</p>
</div>
Script:
<script type="text/javascript">
$(document).ready(function() {
$('.item').delay('1000').fadeIn('1000');
});
</script>
http://jsfiddle.net/CYGNp/1/
Related
I have this JQuery code and a link below the JS code. It doesn't seem to work if the link is below the JS code, but it works if the JS code is below the link.
How can I get it working with the JS code above the link? I need to do it this way because I have the JS code in a file that I include using PHP include.
<div id="EditPage" class="EditPagePopup">
<iframe id="EditPageFrame" width="100%" height="80%" src=""></iframe>
<a id="JQueryClose">×</a>
</div>
<script>
$("a#EditPageLink").click(function (e) {
alert("f");
e.preventDefault();
$("#EditPageFrame").attr("src", $(this).attr("value"));
$("a").removeClass("active");
$(this).addClass("active");
JQueryPopup('#EditPage');
});
</script>
<a id="`EditPageLink`" href="#" value="editcustomer.php?seq='.$customer["sequence"].'"
It doesn't need to be, but it's recommended to be. Read this previously asked question.
What you should definitely do, is use jQuery's ready function to ensure the DOM has finished loading before attaching your events. For example:
$(function() {
$("a#EditPageLink").click(function (e) {
alert("f");
e.preventDefault();
$("#EditPageFrame").attr("src", $(this).attr("value"));
$("a").removeClass("active");
$(this).addClass("active");
JQueryPopup('#EditPage');
});
});
Doing that will attach the event correctly, regardless of where your script tag appears in the html.
When the code is above the html, then it might get executed before the DOM is fully loaded. It's recommended to put your javascript that depends on the DOM at the bottom of the page to avoid this problem.
Having scripts all the way to the bottom has become the usual practice because that way the browser can render the page and load and run scripts last.
It used to be all scripts inside the head tag, way back then. But really you can put the script wherever, having all in one place (top or bottom) makes your markup readable and maintainable.
I'm trying to do a .show() on page load, however, the div is not yet loaded
It looks like jquery is running before a certain div has been created.
Wondering how can I solve this ?
my code consists of the following:
<script>
function choose_category(category_id)
{
$('#' + category_id).show(); // this is the part which doesn't work, as on page load the div mentioned later is not yet available.
}
</script>
<script>
function load()
{
choose_category('<?php echo $model->category_id->__toString(); ?>');
}
</script>
<img onload="load();" src="http://media.sociopal.com/ires/images/homepage/status-socio-icon.png" alt="" width="0" height="0" style="display:none;"></img>
The html embeds php code which runs a loop and generates (among other divs) the following div:
<div id='thecategoryid!!' onclick='choose_category("51d552eb2c8751766000016d");return false;' class = 'settings_menu_item'>
<p class='settings_menu_item_text'>Design Channels<i class='icon-chevron-right right'></i></p>
</div>
However, as mentioned, when the page loads (only when the page loads) the .show() does nothing because it looks like the div is not yet created.
If I debug this in chrome and go step-by-step, there is no problem (the div is created on time and the .show() works fine)
Will appreciate your help.
I can see no error in the code you have posted.
It might be that your assumption of what $.show() does is wrong.
$.show simply removes any occurences of "display: hidden;" in the inline styling of the selected element/node.
<div style="color:red; display:none;">
would become
<div style="color:red;">
http://api.jquery.com/show/
Instead of using that inline onload stuff, try this giving your image an id (we'll use img here.
Since you are calling choose_category with an inline click event listener, do not place that function inside $(document).ready as it won't be able to be accessed.
Then, use the following JavaScript:
$(document).ready(function(){
var img = $("#img");
img.load(function(){
load();
});
if (img[0].complete)
img.load();
});
What this is doing:
When the doc is ready, get the image. Attach a load event listener. If the image has already loaded by the time we got here (especially with caches), trigger a load event anyway.
Also note that you shouldn't put special put exclamation points in your id.
http://jsfiddle.net/DerekL/qDqZF/
$('<img/>').attr('src', "http://derek1906.site50.net/navbar/images/pic3.png").load(function() {
$("body").html("done");
blah blah blah...
})
There I have tested using $("<img/>").load in IE 7, and what I got are these:
When run in counsel, I get this:
"Unable to get value of the property 'attr': object is null or undefined"
When used in my webpage, I get this:
"SCRIPT5007: Unable to get value of the property 'slice': object is null or undefined"
jquery.js, line 2 character 32039
What happened? (Hate IE...)
Ensure that the load function is being executed. I recently dealt with this issue. In IE the load function wasn't firing on cached images. For my purposes I was able to get around this by never allowing the image to cache. ( An ugly solution )
ex:
src="loremIpsum.jpg"
change to:
src="loremIpsum.jpg?nocache=" + new Date().getTime()
Where "nocache" can be changed to anything that makes sense to you.
From the jQuery documentaion:
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"
http://api.jquery.com/load-event/
In IE the load event doesn't always get triggered when the image is cached. Try this:
var img = new Image();
img.src = "http://derek1906.site50.net//navbar/images/pic3.png";
if (img.complete || img.readyState === 4) {
$("body").html("done");
}
else {
$(img).on("load error onreadystatechange",function(e){
if (e.type === "error") {
$("body").html("Image failed to load.");
}
else {
$("body").html("done");
}
});
}
Also, don't forget to wait for the DOMReady event, otherwise $("body") may not exist yet if the image loads fast enough.
jsFiddle
Edit:
I have a plugin that may help simplify image preloading: https://github.com/tentonaxe/jQuery-preloadImages/
So I did some quick testing in jfidde, and pulled out the relevant code and ran it standalone in ie7-8-9. They all ran fine. I can say with confidence that it is not this piece of code that is breaking your page.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title> - jsFiddle demo by DerekL</title>
<script type='text/javascript' src='http://code.jquery.com/jquery-1.7.1.js'></script>
<script type='text/javascript'>
$('<img/>').attr('src', "http://derek1906.site50.net//navbar/images/pic3.png").load(function() {
$("body").html("done");
$("<img/>").appendTo("body").attr("src","http://derek1906.site50.net//navbar/images/pic3.png");
});
</script>
</head>
<body>
Loading...
</body>
</html>
Some ideas though:
Wrap any script in the document head that manipulates the DOM in a document.ready call.
$(document).ready(function(){ go(); });
Search your source code for that slice call. If you are trying to manipulate a jQuery collection with .slice() it will break. jQuery collections are Objects, not Arrays. (may or may not be your problem)
Make sure that any code trying to touch that image is called after the .load() method returns. A common mistake is to do something like:
$('<img id="me" />').attr('src', 'my.jpeg')
.load( function(){ $(this).appendTo("body"); } );
alert( $('#me').attr('src') );
If this is the only image on the page, the above script will likely fail because the appendTo() is called asyncronously, and almost certianly after the following lines of code have executed and failed. Make sure that any logic manipulating that image is run from the .load() callback. (As you have nicely done in your above example code.)
If you paste the rest of your page source I can take a look! Good luck!
add load event first then set img'src
because ie run so fast than when you set the src, "load" event was finished
the new load handler will be executed next change
I'm using Phonegap to build a small (test only) Macrumors application, and remote hosts actually work (there is no same host browser restrictions). I am using the jQuery Load() function to load the contents of the Macrumors homepage http://www.macrumors.com/ into a bin, hidden div, then the each function to loop through all the article classes to show the title in a box with a link to the page.
The problem is, after the Macrumors HTML content is loaded, the each function doesn't work with the article class. Also, in the load function (which allows you to specify certain selectors, id's and classes included, to only load in those sections of the page) the class doesn't work; none of the classes do, in both the load function and each function. And many Id's don't work in the each function either.
Can anybody explain this to a noob like me?
Here is the code:
function onDeviceReady()
{
// do your thing!
$('#bin').load('http://www.macrumors.com/ #content');
$('.article').each(function(){
var title = $('a').html();
$('#content').append('<b>'+title+'</b>')
});
}
And the HTML stuff
<body onload="onBodyLoad()">
<div id="bin">
</div>
<div id="content">
</div>
</body>
I sincerely apologize if there's some very simple mistake here that I'm missing; I'm a major JS newbie.
.load() is asychronous. It hasn't completed yet when you're executing .each(). You need to put your .each() and any other code that wants to operate on the results of the .load() in the success handler for .load().
You would do that like this:
function onDeviceReady()
{
// do your thing!
$('#bin').load('http://www.macrumors.com/ #content', function() {
$('.article').each(function(){
var title = $('a').html();
$('#content').append('<b>'+title+'</b>')
});
});
}
I'm also guessing that your .each() function isn't working quite right. If you want to get the link out of each .article object, you would need your code to be like this so that you're only finding the <a> tag in each .article object, not all <a> tags in the whole document:
function onDeviceReady()
{
// do your thing!
$('#bin').load('http://www.macrumors.com/ #content', function() {
$('.article').each(function(){
var title = $(this).find('a').html();
$('#content').append('<b>'+title+'</b>')
});
});
}
I'm an jQuery noob and I'm wondering how fix this issue:
I have an external .js script, let's take reflection.js as example.
Reflection.js creates canvas reflection for every class="reflect" image.
I'm appending a few images trough different JS script that starts when ('document').ready.
Of course reflection.js doesn't work for images created by the script above.
How to avoid that?
I guess I'll need callback (?). Unfortunately I'm not getting idea of callbacks idea even after reading documentation.
[edit]
<script src="js/reflection.js" type="text/javascript"></script>
<script type="text/javascript">
jQuery().ready(function() {
jQuery('#thumbs li').each(function(){
jQuery('.'+id+' a').append('<img src="' + imgURL + '" class="reflect" /></a>');
});
});
</script>
Image loading events do not bubble. You cannot hook into those.
Since your images have the class "reflect" it means you have some control over the source. So I recommend your reflection code publishes an API for you to call.
window.Reflect = function(img) {
...
};
...
var img = $("<img></img");
img.attr({
...
});
Reflect(img);
...
If you do not want to do this then you can poll the document for new images.
(function poll() {
var images = $("img.reflect");
...
images.removeClass("reflect")
setTimeout(poll, 500);
})();
If I understand this correctly, you have 2 functions under "ready" sequence and one script depends on other.
The way how I solved this problem, I have build my own includeJS as well as additional ready-checking layer on top of the one which jQuery has.
https://github.com/atk4/atk4/blob/master/templates/js/start-atk4.js
So my code looks like this:
$(function(){
$.atk4.includeJS('reflection.js');
$.atk4.includeJS('different.js');
$.atk4(function(){
$('.reflect').reflection();
});
});
What happens is, after document is ready, jQuery launches above code. It appends 2 scripts and evaluates them (by adding tag). When evaluation is complete, function atk4.get will execute readiness chain very similar to how jQuery does it.