Many people have suggested to use jQuery attribute and metadata handling for this. Here I just propose to use a global variable. However, there are few issues you probably faced, so let me explain the solutions:
(1). If you put a global variable, beware of the href="" in your anchors. If you trigger a reload of the page you are back in square zero, not good. So I removed that.
(2). You want to check the global variable in the mouseover and mouseout to do something like
if <triggered from current> return; // disabling check
problem is that in the click function you want to do something like
if <there is a current> current.trigger('mouseout');
<set new current>
current.trigger('mouseover')
but as we are disabling mouseout and mouseover by the disabling check then triggering those doesn't work.
You have two options here: a) you can set current to null, trigger those two events and then set current to the one clicked; b) Or you can isolate the over/out effect from the trigger so you can call it in two places.
Option (a) is a more complex click handler but simpler mouse handler. Option (b) requires little more refactoring, but if you prefer going down the path of using other jQuery features, it is probably a good idea.
(3). Because I am not using jQuery idioms but your approach, one needs to be careful with the regular expression so it matches what it should be. I did this to.
(4). The code below attaches the click to the anchors as in you mentioned (although some solutions mention the images themselves.) The issue here is how you link the clicked object to the corresponding image. In the code below jQuery's find() is the clue.
(5). It is best practice in jQuery not to use global variables, i.e. variables at the window object level. You can still obtain the same result declaring the variable above the closures involved as illustrated below. Also, people like to use $ for variables holding jQuery wrapped objects and I did so.
(6). Finally, beware of object comparison. The code below makes sure we compare DOM objects, so use jQuery's get().
So, this is the amended HTML (removed href):
<a id="anchor1" class="imageLink" ><img class="hoverImage" src="images/1.png"/></a>
<a id="anchor2" class="imageLink" ><img class="hoverImage" src="images/2.png"/></a>
<a id="anchor3" class="imageLink" ><img class="hoverImage" src="images/3.png"/></a>
(sorry, image URLs are not as yours, I actually tested the code below)
Approach (a):
<script type="text/javascript">
$(function() {
var clickedImg = null; // this is common to all closures below
$("img.hoverImage")
.mouseover(function () {
var $img = $(this);
if ($img.get(0) == clickedImg) return;
// note the improved matching !
var src = $img.attr("src").match(/[^_\.]+/) + "_hover.png";
$img.attr("src", src);
})
.mouseout(function () {
var $img = $(this);
if ($img.get(0) == clickedImg) return;
var src = $img.attr("src").replace("_hover","");
$img.attr("src", src);
});
$("a.imageLink").click(function() {
var oldClicked = clickedImg;
clickedImg = null; // set to null to trigger events
if (oldClicked) $(oldClicked).mouseout();
var newClicked = $(this).find('img').get(0);
$(newClicked).mouseover();
clickedImg = newClicked; // redefine at the end
alert($(this).attr('id') + " clicked"); // ajax call here
});
});
</script>
and approach (b):
<script type="text/javascript">
$(function() {
var clickedImg = null; // same global
// refactor the mouse over/out - you could use other jQuery ways here
function doOver($img) {
var src = $img.attr("src").match(/[^_\.]+/) + "_hover.png";
$img.attr("src", src);
}
function doOut($img) {
var src = $img.attr("src").replace("_hover","");
$img.attr("src", src);
}
$("img.hoverImage")
.mouseover(function () {
var $img = $(this);
if ($img.get(0) == clickedImg) return;
doOver($img);
})
.mouseout(function () {
var $img = $(this);
if ($img.get(0) == clickedImg) return;
doOut($img);
});
$("a.imageLink").click(function() {
if (clickedImg) doOut($(clickedImg));
clickedImg = $(this).find('img').get(0);
doOver($(clickedImg));
alert($(this).attr('id') + " clicked"); // presumably your ajax call here
});
});
</script>
Option (a) preserves your structure, but I think option (b) should be your next step and it is my preference.