如何在锚点标签中以编程方式调用onclick()事件,同时在onclick函数中保留“ this”引用?


83

以下内容不起作用...(至少在Firefoxdocument.getElementById('linkid').click()中不起作用:不是函数)

<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>

Answers:


110

您需要apply在该元素的上下文中使用事件处理程序:

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

否则this将引用执行以上代码的上下文。


3
我认为您是唯一一个不把我当傻瓜的人(不用说括号表示法/ onclick | click浏览器不兼容)。发现!
罗普斯塔2009年

3
考虑一下:howtocreate.co.uk/tutorials/javascript/domevents-调用onclick函数会调用所有已注册的事件处理程序吗?同样,错误地调用事件将不会产生与该事件关联的默认操作(例如,表单提交)。
jrharshath,2009年

浓汤,因为这个代码产生-different-结果,它仍然无法与Microsoft.Ajax和Microsoft.AjaxMvc图书馆工作....
Ropstah

1
为什么apply()在这里使用?您可以这样做elem.onclick();elem它将成为函数中的“ this”引用-简单!
Doin

18

解决此问题的最佳方法是使用Vanilla JS,但是如果您已经在使用jQuery,则有一个非常简单的解决方案:

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

在IE8-10,Chrome,Firefox中进行了测试。


3
为什么要下票?请评论一个原因,如果您认为某事有误,那么我可以改善我的问题。
luschn

1
它是在计算器说,你不应该规定依赖于外部资源(如像jQuery库)如果OP没有明确提到关于这个问题,我认为这是它促生了downvote的答案
vhoyer

早在2013年,每个人都在使用jquery-但如今,我同意:)-虽然我会保留答案以供将来参考。
luschn

15

要触发事件,您基本上只需调用该元素的事件处理程序即可。与您的代码略有不同。

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

if (typeof(evnt) == "function") {
    evnt.call(a);
}

1
+1。另外,通过谷歌搜索可以发现foo.click()仅是IE浏览器,我当然可能错了……
karim79,2009年

1
您应该使用点表示法(.onclick),而不是使用括号表示法([“ onclick”])。
拉德·兹沃林斯基

.onclick()或.click()均无法正常工作。在Firefox .click(或带括号的['click'])中,它是“ NOT A FUNCTION”。但是,当调用.onclick()时,您会丢失“ this”引用(我在ASP.NET MVC中需要此引用,因为执行功能需要<a>标记中的信息)
Ropstah,2009年

5
$("#linkid").trigger("click");

2
欢迎来到SO。您能否详细说明其工作原理(它到底能做什么等),还有什么使它与其他解决方案不同?
2015年

2
为什么把这个答案记下来?如果您使用jquery,这是此页面上的最佳解决方案。。。
PodTech.io

答案不需要jQuery
Greg Perham

5

当然,OP非常相似地表示这行不通,但对我来说确实如此。根据我的资料中的注释,它似乎是在OP发布后或之后实施的。也许现在更标准了。

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

就我而言,我的按钮没有ID。如果您的元素具有ID,则最好使用以下内容(未经测试)。

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

我最初尝试了这种方法,但是没有用。谷歌搜索之后,我回来了,意识到我的元素是按名称命名的,并且没有ID。仔细检查您在调用正确的属性。

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


1

看看handleEvent方法
https://developer.mozilla.org/en-US/docs/Web/API/EventListener

“原始” 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);

现在,单击您的元素(ID为“ myElement”),它将在控制台中打印以下内容:

捕获的事件:单击
ABC

这使您可以将对象方法用作事件处理程序,并可以访问该方法中的所有对象属性。

不能只是将对象的方法直接传递给addEventListener(例如:),element.addEventListener('click',myObj.myMethod);并且希望myMethod像在对象上正常调用我那样操作。我猜想传递给addEventListener的任何函数都将以某种方式复制而不是被引用。例如,如果将事件侦听器函数引用传递给addEventListener(以变量的形式),然后取消设置此引用,则在捕获事件时仍将执行事件侦听器。

将方法作为事件侦听器和stil传递this并仍然可以在事件侦听器内访问对象属性的另一个(不太优雅的)解决方法 是:

// see above for definition of MyObj

var myObj = new MyObj();

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

1

旧线程,但问题仍然相关,所以...

(1)在你的问题的例子,现在DOES在Firefox的工作。然而除了调用事件处理程序(显示一条警告),它ALSO点击链接,导致导航(一旦警报被解雇)。

(2)向JUST调用事件处理程序(没有触发导航)仅取代:

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

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

0

如果仅使用此方法在onclick属性中引用该函数,那么这似乎是个坏主意。内联事件通常是个坏主意。

我建议以下内容:

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);

如果要从其他javascript代码中调用相同的函数,模拟单击以调用该函数不是最佳方法。考虑:

function doOnClick() {
   showHref(document.getElementById('linkid'));
}

这是关于保留对“ this”的引用。我不能只在锚点(.NET MVC)中生成onclick部分。我需要生成一个完整的锚标记。onclick函数完全需要此标记(例如,它使用href属性)。
罗普斯塔2009年

-1

通常,我建议您不要“手动”调用事件处理程序。

  • 尚不清楚由于多个注册侦听器而执行了什么
  • 进入递归和无限事件循环的危险(单击A触发单击B,触发单击A等等)
  • DOM的冗余更新
  • 很难将用户引起的视图实际变化与初始化代码(应仅运行一次)进行区分。

更好的方法是弄清楚您到底想要发生什么,将其放入函数中并手动调用并将其注册为事件侦听器。


OP询问如何做某事,而不是做某事的最佳方法是什么。这不是CodeReview。如果您回答了他的问题然后放了免责声明,那将有所不同。
泰勒·蒙尼
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.