views:

746

answers:

6

If I have code like this:

<script>
function determine()
{
    // ????
}
</script>

<a href="blah1" onclick="determine()">blah1</a>
<a href="blah2" onclick="determine()">blah2</a>

Is there a way in determine() to see which link was clicked?

(Yes, I know, the easy and correct thing to do would be to pass "this" to determine()...but in this case that's not going to be easy to do because of legacy code issues.)

EDIT: I probably should have mentioned this at the beginning...our site is not currently using (and cannot use, for the time being) JQuery...so JQuery answers (while valuable in general for this type of question) won't actually help me.

+3  A: 

Check out this link from quirksmode. You can get the event target.

function doSomething(e) {
    var targ;
    if (!e) var e = window.event;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ.nodeType == 3) // defeat Safari bug
     targ = targ.parentNode;
}
Geoff
the jquery answers from others are better than this I think
Geoff
Perhaps, for some, the JQuery answers would be better...but for us, we're not using JQuery right now (and can't use it for the time being)...so this looks like the best solution so far.
Beska
But I thought you indicated that you could not change the onclick="determine()" in your HTML? In that case this example will not solve the problem - you could just change to onclick="determine(this)" and call it a day.
BarelyFitz
you didn't specify browser. This won't work in all browsers without modifying the original onclick.
Geoff
@BarelyFitz: I'm not clear why you're saying this won't solve the problem (especially since, as far as I can tell when trying it, it does). As I said, I can't change the call to add a parameter, or that's what I would do. But this seems to get exactly what I need...in my case I need the href, which I can get by just returning "targ.href" from this function.
Beska
@Beska: if you are not changing the onclick, then this solution might work in IE (because IE has window.event that refers to the most recent event); however, I don't think it will work in other browsers such as Firefox.
BarelyFitz
Gotcha. I see what you're saying...right, I wasn't using this function as given...I was just using the window.event aspect of it, since that's what I needed (since I'm not able to pass an e in). But, as you mentioned, it does not seem to work outside of IE (or at least, not in Firefox, which is all I bothered to test).
Beska
A: 

you could add events to each link like so

links = document.getElementsByTagName('a');

for (link in links) {

   link.onclick = function() {
      alert(this.id);
      determine(); // or some other important code?
   }

}
Ozzy
Don't use for..in to iterate over arrays or array-like objects like node lists! Also, there's no need for `getElementsByTagName()` - `document.links` does the job as well
Christoph
+2  A: 

You can with straight up JavaScript, but I prefer to use something like jQuery:

<a href="blah1">blah1</a>

<script type="text/javascript">
  $('a[href=blah1]').click(function() {
    var link = $(this); // here's your link.
    return false; // acts like the link was not clicked. return true to carry out the click.
  });
</script>

Assuming you are using the $().click() functionality, $(this) will give you the link.

swilliams
+1  A: 

If you cannot change the onclick="determine()" in your HTML, but you can change the determine() function, then I think your best bet is to:

Leave the determine() function blank so it doesn't do anything.

Use javascript (as described by other answers) to add a real click handler to each link, and use the event to determine which link was clicked then execute the desired code.

BarelyFitz
A: 

Another solution:

Add an onclick handler to the document. When a user clicks the link, the click event will "bubble" up to the window, and you will have access to the event to determine which link was clicked.

This might be useful if you only want the code to run for those links that already have onclick="determine()" - you could set the determine() function to set a variable. Then when the user clicks the link, the determine() function runs to set the variable, and when the document click handler runs you could check for the variable - then you will know that the link had onclick="determine()".

Let me know if I can make this a little more complicated for you... :-)

BarelyFitz
A: 

If you can't change the onclick attribute, patch it via JavaScript:

// use a DOMContentLoaded hack or `onload` as fallback
onload = function() {
    var links = document.links;
    for(var i = 0; i < links.length; ++i) {
     // there might be a better way to check which links to modify
     // don't know without further details
     if(/determine\(\)/.test(links[i].onclick))
      links[i].onclick = determine;
    }
};

function determine() {
    // the link is now available as `this`
    alert(this.href);
}

Perhaps an even better solution would be to patch in a global, IE-style event object for standards compliant browsers:

if(document.addEventListener) {
    document.addEventListener('click', function(e) {
     window.event = e;
    }, true);
}

function determine() {
    var src = event.target || event.srcElement;
    alert(src.href);
}
Christoph