6

I have an anchor tag element coming in the html like:

<a href="javascript:handleEvent(this, 'abc')"></a>

Now in the javascript function, I have written:

function handleEvent(sourceElement, txt) {
    console.log(sourceElement);
}

the consoled element is coming as the window in this case. I tried sourceElement.document.activeElement but it doesnt seem to work in chrome, where it is coming as body element.

I cannot change the structure of the anchor tag to 'onClick' function as this is coming from some other source. Is there some way to find the calling element in this scenario?

Kop4lyf
  • 4,520
  • 1
  • 25
  • 31
  • possible duplicate of [get the event object in an event handling function without pass the event object as parameters? (with jquery)](http://stackoverflow.com/questions/5849370/get-the-event-object-in-an-event-handling-function-without-pass-the-event-object) – pwolaq Feb 03 '14 at 10:59
  • 3
    @Pawel_W: No, there's a big difference between `href="javascript:..."` and `onclick="..."`. – T.J. Crowder Feb 03 '14 at 11:04

4 Answers4

4

The real answer here is to change the HTML, which you've said you can't do. I'd push back on that if you can. If you're writing the function, and the function name is in the HTML, how is it you can't change the HTML??

But if you really, really can't, you can update the DOM once it's loaded:

var list = document.querySelectorAll('a[href^="javascript:"]');
var x, link;
for (x = 0; x < list.length; ++x) {
    link = list[x];
    link.onclick = new Function(link.href.substring(11));
    link.href = "javascript:;";
}

Live Copy | Live Source

This is fairly naughty, as it uses the Function constructor (which is very much like eval), but if you trust the source of the HTML, that should be okay.

Or of course, if you don't have to use whatever was in the href to start with, just hook up your event handler in the code above and don't use new Function.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

If you have access to the js, you could do something like this:

document.addEventListener('DOMContentLoaded', function(){
    var link = document.querySelectorAll('a');
    link[0].addEventListener('click', function(e){
        console.log(e.target);
    });
});

With this, you would be just not be doing anything with the inline href event and just be appending your own handler.

Joe
  • 6,401
  • 3
  • 28
  • 32
  • This answer is wrong on various levels: adding a listener does not make another piece of event-handling code magically disappear. This also doesn't bind a handler to _all_ elements, but only to the first anchor element of the DOM. `querySelectorAll` is also better supported than some of the newer `getElementsBy*` functions (`getElementsByClassName` for example), use that whenever you can. Also it's best to specify the third argument you pass to `addEventListener` – Elias Van Ootegem Feb 03 '14 at 11:32
  • @EliasVanOotegem A few things about your comment: 1) I never said that adding the event listener would make the inline declaration disappear. I explicitly said that the OP would simply be ignoring the inline declaration. 2) The OP said he had AN anchor element; hence the index of 0. Obviously if he wanted to bind to all anchors, it would be a different process. 3) Updated to use `querySelectorAll`. – Joe Feb 03 '14 at 11:41
  • _"With this, you would be ignoring the inline href"_ <-- no, you wouldn't – Elias Van Ootegem Feb 03 '14 at 11:43
1

try something like this, use jQuery

just select the link tag with your selector

        $(function(){
            var href = $('a').attr('href');
            href = href.replace('javascript:','');
            $('a').attr('href','#');
            $('a').attr('onclick',href);
        })

This is just workaround solution.

rajesh kakawat
  • 10,826
  • 1
  • 21
  • 40
  • `onclick` and `href` are not equivalent. `href` can be used with a keyboard. `onclick` can be used only with a mouse. – ceving Jul 26 '17 at 12:18
1

And if no other answer here works for you because you can't update the DOM after it's loaded (try doing any of them if you want to modify a squarespace lightbox - not saying it's impossible, but...), here's an out of the box thinking:

Sometimes there will be something hinting where the a href is. So you could use it.

<div class="hint current">
    <a href="javascript:handleEvent('.hint')">

In my case, I even knew the hint without needing a parameter, which made things even simpler:

function handleEvent (hint) {
    if(!hint) {
        hint = $("div.current");
    }
    hrefElement = $(hint).find('a[href^=javascript]');
}

This of course will make sense if your DOM is constantly being changed by a script you have no access to.

But even if there is nothing hinting on the a href, you still could do something like this:

<a href="javascript:var x=1;handleEvent(1)">

function handleEvent (uniqueId) {
    hrefElement = $('a[href^=javascript:var x='+uniqueId);
}
cregox
  • 17,674
  • 15
  • 85
  • 116
  • 1
    Cawas, as per my understanding, this answer works well for simple htmls, but the html I encountered at that time were really complicated. There were 100 of elements without any class/id, looking exactly same but just the difference was in the href event. In that case you cannot use .find to get the element as we dont know which one invoked the function. That was the reason on changing it to onclick as I could get the element easily. – Kop4lyf Feb 11 '15 at 10:21
  • There's nothing simple in squarespace lightbox, but it is well organized. It's just different situations, I suppose. In my case, no other answer worked. ;) (now I see I should reword the idea and focus on this, thanks) – cregox Feb 11 '15 at 13:16
  • Agreed totally!!! By the way, the html I was getting was of a Jaspersoft report if you wanna check out. – Kop4lyf Feb 12 '15 at 06:34
  • Cool stuff. Re-reading your comment, I had an idea... Even if the only hint is whatever you write on the `href`, you still could use this. The more awesome part is it becomes self hintable! I'll edit the answer again. – cregox Feb 12 '15 at 07:36