如何使用JavaScript设置onClick事件?

49

我正在尝试使用JavaScript设置onclick事件。以下代码有效:

var link = document.createElement('a');
link.setAttribute('href', "#");
link.setAttribute('onclick', "alert('click')");

然后,我使用appendChild将链接添加到文档的其他部分。

但显然我想要一个比警报更复杂的回调,所以我尝试了这个:

link.onclick = function() {alert('clicked');};

而这个:

link.onclick = (function() {alert('clicked');});

但是这样做没有任何效果。当我点击链接时,什么也不会发生。我使用Chrome进行测试,并浏览DOM对象时发现该元素的onclick属性为NULL。

为什么我无法将函数传递给onclick?

编辑:

我尝试使用下面建议的addEventListener,但结果相同。链接的DOM显示onclick为空。

我的问题可能是该元素的DOM可能尚未完全构建。此时页面已加载,用户单击按钮。按钮执行JavaScript代码,构建一个新的div并通过调用document.body.appendChild将其附加到页面上。此链接是新div的成员。如果这是我的问题,我该如何解决它?


3
尝试使用 addEventListener('click', function() {...}) - David G
1
我最终写了一篇关于这个的文章(http://heyjavascript.com/setting-and-changing-the-onclick-attribute-with-javascript/)。 - Elliot Bonneville
1
link.onclick = function () { ... }; 应该可以工作:http://jsfiddle.net/sZHkt/1/ - Šime Vidas
对我来说可以运行,不确定问题出在哪里。 - mpm
你提供的链接都可以正常使用。设置 onclick 的 JavaScript 代码是正确的,应该会像其他人说的那样正常工作,但是在我的脚本中却由于某种原因无法正常运行。我尝试在我的环境之外获取一个能够重现这个错误的示例,但是一直没有成功。 - mjr
显示剩余3条评论
6个回答

42

我无法重现这个问题。与楼主的发现相反,下面的代码在线上最新版本的IE、FF、Opera、Chrome和Safari浏览器中都能正常工作。

link.onclick = function() {alert('clicked');};

您可以访问此jsFiddle在您自己的浏览器上测试:

http://jsfiddle.net/6MjgB/7/

假设我们在 html 页面中有以下内容:

<div id="x"></div>

我尝试过的浏览器上面,下面的代码都能正常运行:

var link = document.createElement('a');
link.appendChild(document.createTextNode("Hi"));
link.setAttribute('href', "#");
link.onclick= function() {link.appendChild(document.createTextNode("Clicked"));}

document.getElementById("x").appendChild(link);

如果出现浏览器兼容性问题,使用jQuery可以解决此问题并使代码更加简洁:

var $link = $("<a>").html("Hi").attr("href","#").click(function (){$link.html("Clicked")})

$("#x").html($link)

如果简洁性不足以成为使用jQuery的充分理由,那么浏览器兼容性就应该是…反之亦然 :-)

注意:我在代码中没有使用alert(),因为jsFiddle似乎不喜欢它 :-(


我不知道之前为什么不起作用,但是 jQuery 代码似乎神奇地修复了任何问题。 - mjr
jsfiddle不允许使用alert,因为有人可以轻易地创建一个类似于“while(true) alert("gotcha sucka")”的小工具(fiddle),我想我不需要解释为什么这是个问题。 - Werlious
@Werlious 我可能有点困惑,但这为什么会成为问题呢?JSfiddle在客户端上运行沙盒代码,对吧? - reducing activity
是的,假设我与您分享了一个小提琴。在您打开它之前,您不会知道小提琴中的JS是 while(true) alert("harhar")。您打开小提琴查看它是什么时,当jsfiddle加载小提琴时,它还会生成预览,运行js,现在您的计算机正在向您发送垃圾邮件警报,通常比您反应更快地减慢您的浏览器/计算机速度。现在您已经被DOS攻击了。将其替换为例如在stagefright时代的Android上感染的图像,那么您就有了一些真正的问题。 - Werlious

10
如果您正在使用JavaScript进行此操作,则使用addEventListener(),并使用addEventListener('click', function(e) {...})将事件存储为e。如果不这样传递事件,它将无法访问(尽管Chrome似乎足够聪明以找出这一点,但并非所有浏览器都是Chrome)。

完整的工作JSBin演示。

StackOverflow演示...

document.getElementById('my-link').addEventListener('click', function(e) {
  console.log('Click happened for: ' + e.target.id);
});
<a href="#" id="my-link">Link</a>


7

你可以使用addEventListener(...)来添加DOM事件监听器,正如David所说的那样。我已经包含了attachEvent, 以保证IE兼容性。

var link = document.createElement('a');
link.setAttribute('href', "#");
if(link.addEventListener){
   link.addEventListener('click', function(){
      alert('clicked');
   });
}else if(link.attachEvent){
   link.attachEvent('onclick', function(){
      alert('clicked');
   });
}

2

设置属性看起来不太好。最简单的方式就是这样:

link.onclick = function() {
    alert('click');
};

但是像JCOC611建议的那样使用 addEventListener更加灵活,因为它允许你将多个事件处理程序绑定到同一个元素上。请记住,在与旧版本的Internet Explorer兼容时,您可能需要使用attachEvent备用方法。


2
如果你喜欢,可以使用类似这样的东西:
<button id="myBtn">Try it</button>
<p id="demo"></p>

<script>
document.getElementById("myBtn").onclick=function(){displayDate()};

function displayDate()
{
    document.getElementById("demo").innerHTML=Date();
}
</script>

1
如果你有一个已经定义的命名函数,即function funcName() {...},那么过程就是简单地将onclick与函数的名称关联起来。

document.getElementById("myBtn").onclick = displayDate;

function displayDate() {
    document.getElementById("demo").innerHTML=Date();
}
<button id="myBtn">Try it</button>
<p id="demo"></p>

这可以帮助保持你的代码更好地组织。一个函数可能会很长,将其单独定义为一个单一的onclick,而不是一些可以在后面引用的独立变量,可能会导致代码混乱不堪。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接