如何使用JavaScript模拟点击?

442

我想知道如何使用JavaScript模拟点击一个元素。

目前我有这样的代码:

function simulateClick(control) {
  if (document.all) {
    control.click();
  } else {
    var evObj = document.createEvent('MouseEvents');
    evObj.initMouseEvent('click', true, true, window, 1, 12, 345, 7, 220, false, false, true, false, 0, null );
    control.dispatchEvent(evObj);
  }
}
<a href="http://www.google.com" id="mytest1">test 1</a><br>

<script type="text/javascript">
    simulateClick(document.getElementById('mytest1'));
</script>

但它不起作用 :(

有什么想法吗?


12
“五个最常见的编码错误”:http://javascript.about.com/od/hintsandtips/a/worst_4.htm - 目前几乎没有人再使用 IE4 浏览器,因此不再需要支持 document.all DOM。但令人惊讶的是,仍有很多人在他们的编码中使用它。更糟糕的是,通常会测试对 document.all DOM 的支持,以确定所使用的浏览器以及是否支持它,如果支持,则代码假定浏览器是 Internet Explorer(这种用法是完全错误的,因为Opera也能识别该DOM)。 - zaf
2
请看https://dev59.com/3HM_5IYBdhLWcg3wUxjF - Crescent Fresh
大多数这些解决方案的问题在于,被点击的元素不会像用户用鼠标单击它那样获得焦点。但是简单地添加 element.focus() 就可以解决这个问题。 - Jordan
@zaf,那个链接已经失效了,现在会跳转到404页面,但是可以在这里找到存档。所讨论的文章非常好。https://web.archive.org/web/20150906012912/http://javascript.about.com/od/hintsandtips/a/worst_4.htm - Hermanboxcar
@zaf,那个链接已经失效了,现在会跳转到404页面,但是可以在这里找到存档。所讨论的文章非常好。https://web.archive.org/web/20150906012912/http://javascript.about.com/od/hintsandtips/a/worst_4.htm - undefined
16个回答

630

那么,像这样简单的东西怎么样:

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

甚至IE也支持


1
@HermannIngjaldsson 是的,在IE浏览器中可以完美运行 - http://msdn.microsoft.com/zh-cn/library/ie/ms536363%28v=vs.85%29.aspx - StudioTime
8
问题是:“它在IE中也能用吗?”- 答案是可以 - 据我所知,至少支持到IE8,没有检查过IE7。 - StudioTime
45
之前这个东西不存在吗?为什么2010年的答案没有提到这个简单的解决方案?只是好奇... - Parth
4
目前在桌面端工作得很好,但不能保证在移动浏览器上正常运行。即使Mozilla开发者网站也不显示移动支持。 - le0diaz
51
或许它确实有作用,只是对于他们来说没有“点燃”。 - Andrew
显示剩余8条评论

523
[编辑于2022年] 这个答案已经非常过时了,现在需要进行现代化更新。使用 element.dispatchEvent 和一个新创建的Event来实现所需类型的事件。以下是使用事件委托的示例。如果想要尝试,请fork这个stackblitz项目

// Note: {bubbles: true} because of the event delegation ...
document.addEventListener(`click`, handle);
document.addEventListener(`virtualhover`, handle);

// the actual 'trigger' function
const trigger = (el, etype, custom) => {
  const evt = custom ?? new Event( etype, { bubbles: true } );
  el.dispatchEvent( evt );
};

// a custom event ;)
const vHover = new CustomEvent(`virtualhover`, 
  { bubbles: true, detail: `red` });


setTimeout( _ => 
  trigger( document.querySelector(`#testMe`), `click` ), 1000 );

function handle(evt) {
  if (evt.target.id === `clickTrigger`) {
    trigger(document.querySelector(`#testMe`), `click`);  
  }
  
  if (evt.type === `virtualhover`) {
    evt.target.style.color = evt.detail;
    return setTimeout( _ => evt.target.style.color = ``, 1000 );
  }
  
  if (evt.target.id === `testMe`) {
    document.querySelector(`#testMeResult`)
      .insertAdjacentHTML(`beforeend`, `<p>One of us clicked #testMe. 
        It was <i>${evt.isTrusted ? `<b>you</b>` : `me`}</i>.</p>`);
    trigger(
      document.querySelector(`#testMeResult p:last-child`), 
      `virtualhover`, 
      vHover );  
  }
}
body {
  font: 1.2rem/1.5rem verdana, arial;
  margin: 2rem;
}

#testMe {
  cursor: pointer;
}

p {
  margin: 0.2rem 0;
}
<div id="testMe">
  Test me can be clicked
</div>

<p><button id='clickTrigger'>Click #testMe</button></p>

<div id="testMeResult"></div>

旧答案:

Here's what I cooked up. It's pretty simple, but it works:

function eventFire(el, etype){
  if (el.fireEvent) {
    el.fireEvent('on' + etype);
  } else {
    var evObj = document.createEvent('Events');
    evObj.initEvent(etype, true, false);
    el.dispatchEvent(evObj);
  }
}

12
我已经添加了一个示例到这个jsfiddle上:http://jsfiddle.net/KooiInc/W4BHD/ - KooiInc
5
在Chromium浏览器中证明这个有效:使用document.querySelector('[value="2706236"]').nextSibling.nextSibling.dispatchEvent(ev);进行加1 :) - PointedEars
95
我尝试了你的JavaScript代码在点赞按钮上 :) (当然有效) - 0fnt
23
Event.initEvent现在已经被弃用,请参考https://developer.mozilla.org/en/docs/Web/API/Event/initEvent。 - artnikpro
1
如果有人尝试在没有与上面帖子中的ev事件相同的上下文环境下运行您的代码片段,那么代码将无法正常工作。只需执行.click()会更加简洁和易读 :) - Alfredo Gallegos
显示剩余20条评论

84

您是否考虑使用jQuery来避免所有的浏览器检测?使用jQuery,它将变得非常简单:

$("#mytest1").click();

22
这只触发jQuery事件处理程序,而不是默认行为(在这种情况下,浏览器转到href)。 - Romuald Brunet
12
我不知道是否会让人感到悲伤,但不必一遍又一遍地重新编写相同的浏览器检测程序确实很方便。 - BradBrening
10
@ErikAigner:我也在想同样的问题,但很高兴这个问题的被接受的答案是纯JavaScript而不是jQuery。在 Stack Overflow 上已经看到太多次了。再说一遍:jQuery 是 JavaScript,但 JavaScript 不是 jQuery。虽然我喜欢用 jQuery,但越来越多的开发者不理解真正的基础知识。我的观点是,忍不住要评论一句。 ;) - Sander
67
如果有些人必须手洗衣服的话,可能不知道该从哪里开始,因为大多数家庭都拥有洗衣机,几乎同样数量的家庭也有烘干机。就像现代家电一样,jQuery使得一项老旧的家务更加容易和少出差错。虽然它并非适用于所有人,但是如果一个回答使用更简明易懂的语法,并且在跨浏览器兼容性方面准确地回答了问题,那么将其投票降低似乎是反向思考的。+1。 - FreeAsInBeer
5
@FreeAsInBeer 如果开车更方便的话,那么你也不应该步行。但我们都知道这很愚蠢。如果不需要走远路,那么就步行。如果需要做一些简单的事情并且不想加载整个库来完成它,就使用普通的JavaScript。没有必要为简单的事情浪费油/带宽。 - Jacob
显示剩余3条评论

31
var elem = document.getElementById('mytest1');

// Simulate clicking on the specified element.
triggerEvent( elem, 'click' );

/**
 * Trigger the specified event on the specified element.
 * @param  {Object} elem  the target element.
 * @param  {String} event the type of the event (e.g. 'click').
 */
function triggerEvent( elem, event ) {
  var clickEvent = new Event( event ); // Create the event.
  elem.dispatchEvent( clickEvent );    // Dispatch the event.
}

参考资料


4
我相信这应该是目前最好的答案。 - DavidTaubmann
1
现在只需使用 element.click(); 就可以了,大多数主流浏览器都支持此功能。请参见 https://dev59.com/BHE85IYBdhLWcg3wl0nF#25806894 和 https://dev59.com/5HE95IYBdhLWcg3wRLwt#2381612。 - Ryan
这是对我有效的答案,它会触发一个点击事件,就像用户在浏览器上单击一样,而不是调用目标上的onclick事件,如element.click(); - hugholousk

15

通过使用jQuery,您可以节省大量空间。 您只需要使用:

$('#myElement').trigger("click")

12
OP 要求使用 JavaScript,虽然 jQuery 紧凑且功能强大,但有些人更喜欢不依赖库的 JavaScript。 - user3856347
58
通过下载jQuery来节省空间? - M H
11
有些人也喜欢使用汇编语言。 - Dan Nissenbaum
@MH 我认为一个更有说服力的论点是“保持简单”。你在SO上的默认配置文件大约与jQuery的大小相同。 - adelriosantiago

10
在JavaScript中,通过id或class名称获取元素,然后应用.click()使点击事件发生,例如:
document.getElementById("btnHandler").click();

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community
坏机器人!最简单、最快、可行的解决方案。 - Dan Rayson

8

最佳答案是最好的!但是,当etype = 'click'时,在Firefox浏览器中它并没有触发鼠标事件。

因此,我将document.createEvent改为'MouseEvents',问题就解决了。额外的代码用于测试另一段代码是否干扰了事件,如果被取消,我会将其记录到控制台。

function eventFire(el, etype){
  if (el.fireEvent) {
    el.fireEvent('on' + etype);
  } else {
    var evObj = document.createEvent('MouseEvents');
    evObj.initEvent(etype, true, false);
    var canceled = !el.dispatchEvent(evObj);
    if (canceled) {
      // A handler called preventDefault.
      console.log("automatic click canceled");
    } else {
      // None of the handlers called preventDefault.
    } 
  }
}

6

模拟事件与创建自定义事件类似。若要模拟鼠标事件:

  • 我们需要使用 document.createEvent() 创建 MouseEvent
  • 然后使用 initMouseEvent() 设置即将发生的鼠标事件。
  • 最后在您想要模拟事件的元素上分派鼠标事件。

在以下代码中,我使用了setTimeout,以便在1秒后自动点击按钮。

const div = document.querySelector('div');

div.addEventListener('click', function(e) {
  console.log('Simulated click');
});

const simulatedDivClick = document.createEvent('MouseEvents');

simulatedDivClick.initEvent(
  'click', /* Event type */
  true, /* bubbles */
  true, /* cancelable */
  document.defaultView, /* view */
  0, /* detail */
  0, /* screenx */
  0, /* screeny */
  0, /* clientx */
  0, /* clienty */
  false, /* ctrlKey */
  false, /* altKey */
  false, /* shiftKey */
  0, /* metaKey */
  null, /* button */
  null /* relatedTarget */
);

// Automatically click after 1 second
setTimeout(function() {
  div.dispatchEvent(simulatedDivClick);
}, 1000);
<div> Automatically click </div>


3

如果事件没有被触发,请使用超时设置

setTimeout(function(){ document.getElementById('your_id').click(); }, 200); 

3

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