Reputation: 869
I'm doing a javascript assignment and have just learned that I can do it in jQuery if I wish, rather than vanilla javascript. I thought I'd give it a go to see what it's like.
This is the contents of my javascript function:
rowsArray = $("#Table1 tr");
for (i=0;i<rowsArray.length;i++){
numSeatsInRow = rowsArray[i].getElementsByTagName("img").length; // discovers the number of seats in row [i]
for(j=0;j<numSeatsInRow;j++) { // loops round once for each set in row [i]
var currentSeat = rowsArray[i].getElementsByTagName("img")[j];
currentSeat.setAttribute("id","row" + i + "Seat" + j);
currentSeat.onmouseover = function(){this.src = "images/taken.gif"};
currentSeat.onmouseout = function(){this.src = "images/available.gif"};
currentSeat.onclick = function() {
this.src = "images/mine.gif";
this.onmouseover = null;
this.onmouseout = null;
document.getElementById("myTickets").innerHTML += this.id;
}
}
As you can see, I started converting to jQuery with the first line, but got stuck :)
The code works as is, but I figure there must be a more elegant way of doing it in jQuery. I tried using $.each but my selectors or syntax was wrong and it didn't work. I have a vague idea how it works for a 1D array, but I'm not clear on how to iterate through the items in nested arrays i.e. array[x][y].
The function creates and moves through a 2D array changing the id and mouse events of a set of images.
Any thoughts would be much appreciated :)
Upvotes: 0
Views: 361
Reputation: 630429
It can be improved further, but something like this would work:
$("#Table1 tr").each(function(i) {
$(this).find("img").each(function(j) {
this.id = "row" + i + "Seat" + j;
$(this).hover(function() { this.src = "images/taken.gif"; },
function() { this.src = "images/available.gif"; })
.click(function() {
var img = this;
this.src = "images/mine.gif";
$(this).unbind("mouseenter mouseleave");
$("#myTickets").html(function(i, h) { return h + img.id; });
});
});
});
Using .each()
and the index it passes as the first parameter to the callback shortens it a bit (you don't need your own i
and j
, they're already there) the rest is just jQuery conversion, e.g. .hover()
for the mouse entering/leaving and .unbind()
to remove those handlers it later.
Here's a bit more verbose but much more efficient version using .delegate()
:
$("#Table1 tr").each(function(i) {
$(this).find("img").each(function(j) {
this.id = "row" + i + "Seat" + j;
});
});
$("#Table1").delegate("tr img", "click", function() {
var img = $(this).addClass("mine").add("src", "images/mine.gif");
$("#myTickets").html(function(i, h) { return h + img.attr("id"); });
}).delegate("tr img:not(.mine)", "mouseenter", function() {
this.src = "images/taken.gif";
}).delegate("tr img:not(.mine)", "mouseleave", function() {
this.src = "images/available.gif";
});
This attaches only 3 handlers to the <table>
and listens for events to bubble up, rather than attaching 3 handlers per image, so it's much cheaper on the page load side, and and infinitesimal difference on the runtime side.
Upvotes: 2
Reputation: 22719
This is untested, but should give you what you need to get things working.
rowsArray = $("#Table1 tr");
for (i=0;i<rowsArray.length;i++){
var images = rowsArray.eq(i).find("img");
numSeatsInRow = images.length; // discovers the number of seats in row [i]
for(j=0;j<numSeatsInRow;j++) { // loops round once for each set in row [i]
var currentSeat = images.eq(j);
currentSeat.attr("id","row" + i + "Seat" + j);
currentSeat.mouseover(function(){this.src = "images/taken.gif"});
currentSeat.mouseout(function(){this.src = "images/available.gif"});
currentSeat.click(function() {
var self = $(this);
self.attr("src", "images/mine.gif");
self.unbind("mouseover");
self.unbind("mouseout");
$("#myTickets").html(this.id);
});
}
Upvotes: 1