ph***********@googlemail.com wrote:
hello i am a newbie to Javascript with a in depth background of PHP
i have a simple script that replaces missing images when the webpage
loads
but i just cant get it to validate in JLint as my javascript skills
are not up to scratch yet
please can somebody help me validate this and ensure that it functions
correctly
Although your posting style really is atrocious (please read what you wrote
and imagine yourself to be a complete stranger, like someone reading your
job application), I am making an exception here (for reasons that will
become obvious later).
function fixBrokenImages(){
var imglst = document.images;
for(var i = 0; i < imglst.length; i++){
imglst[i].onerror = function()
{this.src = "/noimage.png";}
imglst[i].src = imglst[i].src;
}
}
This cries out for code style (I do hope your so very background-supported
PHP scripts don't look like above either):
function fixBrokenImages()
{
var imglst = document.images;
for (var i = 0; i < imglst.length; i++)
{
imglst[i].onerror = function() {
this.src = "/noimage.png";
}
imglst[i].src = imglst[i].src;
}
}
Now that we can see at a glance what's going on, let's look at what JSLint
said, without any options checked (which you should have posted in the first
place!):
| Implied global: document 2
ISTM you can safely ignore that one. By default, JSLint only checks against
the ECMAScript Language Specification, it does not know that browsers (HTML
UAs in general) provide an API with host objects, like the one that can be
referred to by `document'. If you check the "Assume a browser" option that
error-warning will go away.
| Problem at line 6 character 1: Be careful when making functions within a
| loop. Consider putting the function in a closure.
|
| imglst[i].src = imglst[i].src;
That's more serious, if misleading. The relevant lines are instead
(pretty-printed):
imglst[i].onerror = function() {
this.src = "/noimage.png";
}
That function is created within a loop, through a function expression. If
the function contained the `i' variable of the loop, when called it would
resolve that identifier to the last value `i' was assigned to (probably
imglst.length), not to the value that it had when the function was created.
*Another* closure (a closure is what causes this behavior in the first
place, actually) around it would prevent that, however what is described in
the message is not the case here; `i' is used outside of the function, which
is safe.
We have discussed this here numerous times before, ad nauseam, if I may say
so again.
And finally:
| Problem at line 5 character 29: Missing semicolon.
|
| {this.src = "/noimage.png";}
This is not a problem per se. ECMAScript implementations do automatic
semicolon insertion. So, in contrast to PHP, you do not need to write
trailing semicolons in general to make your code syntactically correct.
However, what is a feature can introduce semantical problems if you do
not know how it works. So it is best to adopt "PHP semicolon style"
here, if you will: always end simple statements, such as assignments,
with a semicolon.
Here the statement is
anObject.aProperty = aFunctionObjectReference
so it should be
imglst[i].onerror = function() {
this.src = "/noimage.png";
};
// ^ semicolon there
(Do not let yourself be deceived by the fact that there is a semicolon in
the function body; that delimits only the "inner" assignment, not the
"outer" one.)
Bottom line is that you should take everything JSLint says with a grain of
salt, and you should use the options to enable more lenient checking.
IMHO, JSLint is _not_ to be considered a validator; due to the differences
in implementations it hardly can be that. What runs in one language
implementation might not run in another, see
<http://PointedEars.de/es-matrix>. So you should always test your code in
all known language implementations (which are pretty much related to the
different HTML UAs that support them) and maybe even different versions thereof.
And what might run in one DOM implementation might also not run in another,
so you should always test your code in all known DOM implementations and
maybe even different versions thereof.
What is marked as an error in JSLint might only be a warning or a matter of
Douglas Crockford's taste; and, unfortunately, even then there appear to be
problems in recognizing the context of an expression.
Now that's clarified, it's time for a little optimization of your code:
function fixBrokenImages()
{
var imglst = document.images;
for (var i = imglst.length; i--;)
{
imglst[i].onerror = function() {
// NOTE: prevents this from going into a "loop"
// if the replacement image is not there
this.onload = this.onerror = null;
this.src = "/noimage.png";
};
// TODO: does not make sense
imglst[i].src = imglst[i].src;
}
}
HTH
P.S.: When you reply or make a new thread here, please adhere to
<http://jibbering.com/faq/#postingpp.
PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee