93

The following doesn't work... (at least not in Firefox: document.getElementById('linkid').click() is not a function)

<script type="text/javascript">
    function doOnClick() {
        document.getElementById('linkid').click();
        //Should alert('/testlocation');
    }
</script>
<a id="linkid" href="/testlocation" onclick="alert(this.href);">Testlink</a>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ropstah
  • 17,538
  • 24
  • 120
  • 194

9 Answers9

120

You need to apply the event handler in the context of that element:

var elem = document.getElementById("linkid");
if (typeof elem.onclick == "function") {
    elem.onclick.apply(elem);
}

Otherwise this would reference the context the above code is executed in.

Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • 3
    I think you're the only one not seeing me as a fool (for not mentioning the bracket notation / the onclick|click browser incompatibility). Spot on! – Ropstah May 25 '09 at 12:56
  • 3
    consider this: http://www.howtocreate.co.uk/tutorials/javascript/domevents -- will calling the onclick function invoke *all* event handlers registered? Also, falsely invoking an event will not produce the default action associated with that event (eg a form submission). – jrharshath May 25 '09 at 13:08
  • Gumbo, as this code does produce -different- results, it still doesn't work with the Microsoft.Ajax and Microsoft.AjaxMvc libraries.... – Ropstah May 25 '09 at 13:17
  • 2
    Why use `apply()` here? You can just do `elem.onclick();`, and `elem` will be the 'this' reference in the function - simple! – Doin Jun 16 '19 at 01:37
  • Typescript gives: `TS2684: The 'this' context of type '(this: GlobalEventHandlers, ev: MouseEvent) => any' is not assignable to method's 'this' of type '(this: HTMLAnchorElement) => any'.` – Shota Jul 08 '22 at 16:35
22

The best way to solve this is to use Vanilla JS, but if you are already using jQuery, there´s a very easy solution:

<script type="text/javascript">
    function doOnClick() {
        $('#linkid').click();
    }
</script>
<a id="linkid" href="/testlocation" onclick="alert(this.href);">Testlink</a>

Tested in IE8-10, Chrome, Firefox.

andyrandy
  • 72,880
  • 8
  • 113
  • 130
  • 3
    why the downvote? please comment a reason, so i can improve my question if you believe that something is wrong. – andyrandy Sep 13 '16 at 12:28
  • 1
    it is stated on the stackoverflow that you should not provide answers that depends on a external resource (such as a library like jQuery) if the OP did not explicitly mentioned it on the question, I think it was that that motivated the downvote – vhoyer Aug 14 '19 at 18:10
  • back in 2013, everyone was using jquery - but nowadays, i would agree :) - i will keep the answer for future reference though. – andyrandy Aug 17 '19 at 07:48
15

To trigger an event you basically just call the event handler for that element. Slight change from your code.

var a = document.getElementById("element");
var evnt = a["onclick"];

if (typeof(evnt) == "function") {
    evnt.call(a);
}
simplyharsh
  • 35,488
  • 12
  • 65
  • 73
10

Granted, OP stated very similarly that this didn't work, but it did for me. Based on the notes in my source, it seems it was implemented around the time, or after, OP's post. Perhaps it's more standard now.

document.getElementsByName('MyElementsName')[0].click();

In my case, my button didn't have an ID. If your element has an id, preferably use the following (untested).

document.getElementById('MyElementsId').click();

I originally tried this method and it didn't work. After Googling I came back and realized my element was by name, and didn't have an ID. Double check you're calling the right attribute.

Source: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click

Tyler Montney
  • 1,402
  • 1
  • 17
  • 25
7
$("#linkid").trigger("click");
bfontaine
  • 18,169
  • 13
  • 73
  • 107
guest
  • 105
  • 1
  • 1
4

Old thread, but the question is still relevant, so...

(1) The example in your question now DOES work in Firefox. However in addition to calling the event handler (which displays an alert), it ALSO clicks on the link, causing navigation (once the alert is dismissed).

(2) To JUST call the event handler (without triggering navigation) merely replace:

document.getElementById('linkid').click();

with

document.getElementById('linkid').onclick();
Doin
  • 7,545
  • 4
  • 35
  • 37
1

Have a look at the handleEvent method
https://developer.mozilla.org/en-US/docs/Web/API/EventListener

"Raw" Javascript:

function MyObj() {
   this.abc = "ABC";
}
MyObj.prototype.handleEvent = function(e) {
   console.log("caught event: "+e.type);
   console.log(this.abc);
}

var myObj = new MyObj();

document.querySelector("#myElement").addEventListener('click', myObj);

Now click on your element (with id "myElement") and it should print the following in the console:

caught event: click
ABC

This allows you to have an object method as event handler, and have access to all the object properties in that method.

You can't just pass a method of an object to addEventListener directly (like that: element.addEventListener('click',myObj.myMethod);) and expect myMethod to act as if I was normally called on the object. I am guessing that any function passed to addEventListener is somehow copied instead of being referenced. For example, if you pass an event listener function reference to addEventListener (in the form of a variable) then unset this reference, the event listener is still executed when events are caught.

Another (less elegant) workaround to pass a method as event listener and stil this and still have access to object properties within the event listener would be something like that:

// see above for definition of MyObj

var myObj = new MyObj();

document.querySelector("#myElement").addEventListener('click', myObj.handleEvent.bind(myObj));
Rolf
  • 5,550
  • 5
  • 41
  • 61
0

If you're using this purely to reference the function in the onclick attribute, this seems like a very bad idea. Inline events are a bad idea in general.

I would suggest the following:

function addEvent(elm, evType, fn, useCapture) {
    if (elm.addEventListener) {
        elm.addEventListener(evType, fn, useCapture);
        return true;
    }
    else if (elm.attachEvent) {
        var r = elm.attachEvent('on' + evType, fn);
        return r;
    }
    else {
        elm['on' + evType] = fn;
    }
}

handler = function(){
   showHref(el);
}

showHref = function(el) {
   alert(el.href);
}

var el = document.getElementById('linkid');

addEvent(el, 'click', handler);

If you want to call the same function from other javascript code, simulating a click to call the function is not the best way. Consider:

function doOnClick() {
   showHref(document.getElementById('linkid'));
}
David Snabel-Caunt
  • 57,804
  • 13
  • 114
  • 132
  • it's about keeping the reference to 'this'. I cannot solely generate the onclick part in the anchor (.NET MVC). I need to generate a complete anchor tag. This tag is required completely by the onclick function (e.g. it uses the href attribute). – Ropstah May 25 '09 at 12:54
-1

In general I would recommend against calling the event handlers 'manually'.

  • It's unclear what gets executed because of multiple registered listeners
  • Danger to get into a recursive and infinite event-loop (click A triggering Click B, triggering click A, etc.)
  • Redundant updates to the DOM
  • Hard to distinguish actual changes in the view caused by the user from changes made as initialisation code (which should be run only once).

Better is to figure out what exactly you want to have happen, put that in a function and call that manually AND register it as event listener.

hvdd
  • 514
  • 4
  • 7
  • 1
    OP asked how to do something, not what's the best way to do something. This isn't CodeReview. If you had answered his question and then put the disclaimer, that'd be different. – Tyler Montney Dec 27 '17 at 20:41