I have a code for a simple photo gallery that had been writen with jquery, but i think it's overkill to load the entire library for such a simple thing. I want it in raw javascript.
$('#thumbs').delegate('img','click', function(){
$('#largeImage').attr('src',$(this).attr('src').replace('thumb','large'));
$('#description').html($(this).attr('alt'));
});
Also i'm wondering how do I attach a loading spinner to this code. thanks.
jsfiddle
Without using any library, it looks a bit like this, although of course there are other ways to write it:
(function() {
var largeImage = document.getElementById('largeImage'),
description = document.getElementById('description');
document.getElementById('thumbs').onclick = handleGalleryClick;
function handleGalleryClick(event) {
var target;
event = event || window.event; // Handle IE difference
target = event.target || event.srcElement; // Another one
if (target && target.tagName.toUpperCase() === "IMG") {
largeImage.src = target.src.replace('thumb', 'large');
description.innerHTML = target.getAttribute('alt');
}
}
})();
Make sure that script appears at the bottom of your page (just before the closing body
element) or wrap it up in a window.onload
although you won't be happy with how long that takes to occur, as window.onload
happens after all images and such are loaded.
But: I have to agree with Frédéric's and John's comments: It's not overkill to load a library for this, and in the case of jQuery (and Prototype and YUI) you can load via the Google CDN and use something your page visitor probably already has in their cache anyway.
Update: In the comments below, scunliffe pointed out an IE bug that I've blogged in the past that could affect the above, which is magically worked around for you by jQuery. So I thought it might be useful to flag up the various complications that this simple little script has that a good library will sort out for you:
addEventListener
vs. attachEvent
: IE6 through IE8 don't support the DOM2 standard addEventListener
, using Microsoft's own attachEvent
instead. I actually punted on this in the above for simplicity and just used the DOM0 onclick = ...
style, but there's a good reason not to do that: With the DOM0 style, you can only have a single event listener per event per element, and attaching another will detach the previous one. So my code above doesn't play nicely with others, because it will dislodge any previous DOM0 click
handler (and will be dislodged by a DOM0 click
handler attached after the code above runs).event
object: The DOM standard says that the event
object is passed into the event handler as its first argument. IE, instead, uses a global window.event
object. That's the reason for my first "IE difference" above.event
object: ...and similarly, the DOM standard says the actual element on which the event was fired will be the target
property. IE6 through IE8 use srcElement
instead. (There are other differences, too.) Hence my "Another one" comment.document.getElementById
to work correctly, but on IE6 and IE7, it doesn't. It conflates several namespaces rather than working just with id
values....so all in all, this simple little script makes the point fairly well that libraries in general — and a good library in particular — can save you time, keep your site broadly-compatible, and are just generally worth their little cost. I don't know about the others, but for instance jQuery works around the conflation bug for you, but another well-known and well-respected library, Prototype, does not.
(Side note: Before we knock Microsoft too much, let's remember that attachEvent
and srcElement
probably predate the DOM2 spec; Microsoft did a lot of innovating in IE5.5 and IE6. [They invented ajax, for instance.] IE6 was — by far — the best browser available in 2001, due apologies to Opera. That said, IE6 came out after the standard did and so adding the standards stuff at that point, or several years later in IE7, might have been a worthwhile thing to do! But IE9 fixes a lot of this stuff.)
You call it simple, but it's doing somewhat advanced things. To emulate delegate
, you have to attach a click listener on the root container and check for clicks on any <img>
tag.
Not to mention you have to do things like use attachEvent
in IE instead of addEventListener
The code would look something like (untested):
function listen(root, callback) {
var addEvent = 'attachEvent';
if (typeof window.addEventListener === 'function') {
addEvent = 'addEventListener';
}
root[addEvent](function (e) {
if (/img/i.test(e.target.tagName)) {
callback.apply(e.target);
}
}, false);
}
listen(document.getElementById('thumbs'), function () {
document.getElementById('largeImage').src = this.src.replace(/thumb/ig, 'large');
document.getElementById('description').src = this.alt;
});
In fact, as TJ's post shows below, I'm not even handling all of the IE idiosyncrasies. jQuery is not overkill considering all of the browser headaches it solves for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With