如何模拟单击锚点标记?

时间:2022-02-18 00:39:53

I want to simulate a click to an anchor tag with all extras like correct target handling.

我想模拟点击一个锚标记,其中包含正确的目标处理等所有额外内容。

There seems to be a "[click()][3]" method for anchor's DOM object but not all browsers support that. Firefox throws this error:

对于锚点的DOM对象似乎有一个“[click()] [3]”方法,但并非所有浏览器都支持它。 Firefox抛出此错误:

Error: anchorObj.click is not a function

错误:anchorObj.click不是函数

It also works strangely on Opera 10 and Konqueror, causing infinite clicks to happen when it's called inside onclick handler of a surrounding div. I guess only IE8 works fine with it. Anyway I don't want it since major browsers mostly have problems with it.

它在Opera 10和Konqueror上也很奇怪,当它在周围div的onclick处理程序中调用时会导致无限点击。我猜只有IE8可以正常使用它。无论如何我不想要它,因为主流浏览器大多数都有问题。

I found this alternate solution for Firefox in Mozilla forums:

我在Mozilla论坛中找到了Firefox的替代解决方案:

var evt = document.createEvent("MouseEvents"); 
evt.initMouseEvent("click", true, true, window, 
    0, 0, 0, 0, 0, false, false, false, false, 0, null); 
anchorObj.dispatchEvent(evt); 

This seems too ugly and cumbersome for me. I don't know how compatible it is and I want to avoid writing browser specific code as much as possible.

这对我来说似乎太丑陋了。我不知道它是多么兼容,我想尽可能避免编写特定于浏览器的代码。

I can't use location.href = anchorObj.href; because it doesn't handle "target" attribute. I can do some hard coding based on target's value but I'd like to avoid that as well.

我不能使用location.href = anchorObj.href;因为它不处理“目标”属性。我可以根据目标值进行一些硬编码,但我也想避免这种情况。

There is suggestion of switching to JQuery but I'm not sure how well it handles target property either since I haven't worked with it before.

有建议切换到JQuery,但我不知道它处理目标属性有多好,因为我之前没有使用它。

5 个解决方案

#1


62  

Here is a complete test case that simulates the click event, calls all handlers attached (however they have been attached), maintains the "target" attribute ("srcElement" in IE), bubbles like a normal event would, and emulates IE's recursion-prevention. Tested in FF 2, Chrome 2.0, Opera 9.10 and of course IE (6):

这是一个完整的测试用例,模拟click事件,调用附加的所有处理程序(但它们已被附加),维护“target”属性(IE中的“srcElement”),像普通事件一样的气泡,并模拟IE的递归 - 预防。测试了FF 2,Chrome 2.0,Opera 9.10,当然还有IE(6):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
function fakeClick(event, anchorObj) {
  if (anchorObj.click) {
    anchorObj.click()
  } else if(document.createEvent) {
    if(event.target !== anchorObj) {
      var evt = document.createEvent("MouseEvents"); 
      evt.initMouseEvent("click", true, true, window, 
          0, 0, 0, 0, 0, false, false, false, false, 0, null); 
      var allowDefault = anchorObj.dispatchEvent(evt);
      // you can check allowDefault for false to see if
      // any handler called evt.preventDefault().
      // Firefox will *not* redirect to anchorObj.href
      // for you. However every other browser will.
    }
  }
}
</script>
</head>
<body>

<div onclick="alert('Container clicked')">
  <a id="link" href="#" onclick="alert((event.target || event.srcElement).innerHTML)">Normal link</a>
</div>

<button type="button" onclick="fakeClick(event, document.getElementById('link'))">
  Fake Click on Normal Link
</button>

<br /><br />

<div onclick="alert('Container clicked')">
    <div onclick="fakeClick(event, this.getElementsByTagName('a')[0])"><a id="link2" href="#" onclick="alert('foo')">Embedded Link</a></div>
</div>

<button type="button" onclick="fakeClick(event, document.getElementById('link2'))">Fake Click on Embedded Link</button>

</body>
</html>

Demo here.

在这里演示。

It avoids recursion in non-IE browsers by inspecting the event object that is initiating the simulated click, by inspecting the target attribute of the event (which remains unchanged during propagation).

它通过检查事件的目标属性(在传播期间保持不变)来检查启动模拟点击的事件对象,从而避免非IE浏览器中的递归。

Obviously IE does this internally holding a reference to its global event object. DOM level 2 defines no such global variable, so for that reason the simulator must pass in its local copy of event.

IE显然在内部持有对其全局事件对象的引用。 DOM级别2没有定义这样的全局变量,因此模拟器必须传入其本地事件副本。

#2


11  

well, you can very quickly test the click dispatch via jQuery like so

好吧,你可以通过jQuery快速测试点击调度

$('#link-id').click();

If you're still having problem with click respecting the target, you can always do this

如果您仍然遇到点击尊重目标的问题,您可以随时执行此操作

$('#link-id').click( function( event, anchor )
{
  window.open( anchor.href, anchor.target, '' );
  event.preventDefault();
  return false;
});

#3


11  

Quoted from https://developer.mozilla.org/en/DOM/element.click

引用自https://developer.mozilla.org/en/DOM/element.click

The click method is intended to be used with INPUT elements of type button, checkbox, radio, reset or submit. Gecko does not implement the click method on other elements that might be expected to respond to mouse–clicks such as links (A elements), nor will it necessarily fire the click event of other elements.

click方法旨在与按钮,复选框,无线电,重置或提交类型的INPUT元素一起使用。 Gecko没有对可能期望响应鼠标点击的其他元素(如链接(A元素))实现click方法,也不会触发其他元素的click事件。

Non–Gecko DOMs may behave differently.

非Gecko DOM可能表现不同。

Unfortunately it sounds like you have already discovered the best solution to your problem.

不幸的是,听起来您已经发现了解决问题的最佳方案。

As a side note, I agree that your solution seems less than ideal, but if you encapsulate the functionality inside a method (much like JQuery would do) it is not so bad.

作为旁注,我同意你的解决方案似乎不太理想,但如果你将一个功能封装在一个方法中(就像JQuery会做的那样),那就不那么糟了。

#4


4  

There is a simpler way to achieve it,

有一种更简单的方法来实现它,

HTML

HTML

<a href="https://getbootstrap.com/" id="fooLinkID" target="_blank">Bootstrap is life !</a>

JavaScript

JavaScript的

// Simulating click after 3 seconds
setTimeout(function(){
  document.getElementById('fooLinkID').click();
}, 3 * 1000);

Using plain javascript to simulate a click along with addressing the target property.

使用普通的javascript来模拟点击以及寻址目标属性。

You can check working example here on jsFiddle.

您可以在jsFiddle上查看这里的工作示例。

#5


0  

None of the above solutions address the generic intention of the original request. What if we don't know the id of the anchor? What if it doesn't have an id? What if it doesn't even have an href parameter (e.g. prev/next icon in a carousel)? What if we want to apply the action to multiple anchors with different models in an agnostic fashion? Here's an example that does something instead of a click, then later simulates the click (for any anchor or other tag):

上述解决方案均未解决原始请求的一般意图。如果我们不知道锚点的id怎么办?如果它没有id怎么办?如果它甚至没有href参数(例如旋转木马中的上一个/下一个图标)怎么办?如果我们想以不可知的方式将动作应用于具有不同模型的多个锚点,该怎么办?这是一个做一些事情而不是点击的例子,然后模拟点击(对于任何锚点或其他标签):

var clicker = null;
$('a').click(function(e){ 
    clicker=$(this); // capture the clicked dom object
    /* ... do something ... */
    e.preventDefault(); // prevent original click action
});
clicker[0].click(); // this repeats the original click. [0] is necessary.

#1


62  

Here is a complete test case that simulates the click event, calls all handlers attached (however they have been attached), maintains the "target" attribute ("srcElement" in IE), bubbles like a normal event would, and emulates IE's recursion-prevention. Tested in FF 2, Chrome 2.0, Opera 9.10 and of course IE (6):

这是一个完整的测试用例,模拟click事件,调用附加的所有处理程序(但它们已被附加),维护“target”属性(IE中的“srcElement”),像普通事件一样的气泡,并模拟IE的递归 - 预防。测试了FF 2,Chrome 2.0,Opera 9.10,当然还有IE(6):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
function fakeClick(event, anchorObj) {
  if (anchorObj.click) {
    anchorObj.click()
  } else if(document.createEvent) {
    if(event.target !== anchorObj) {
      var evt = document.createEvent("MouseEvents"); 
      evt.initMouseEvent("click", true, true, window, 
          0, 0, 0, 0, 0, false, false, false, false, 0, null); 
      var allowDefault = anchorObj.dispatchEvent(evt);
      // you can check allowDefault for false to see if
      // any handler called evt.preventDefault().
      // Firefox will *not* redirect to anchorObj.href
      // for you. However every other browser will.
    }
  }
}
</script>
</head>
<body>

<div onclick="alert('Container clicked')">
  <a id="link" href="#" onclick="alert((event.target || event.srcElement).innerHTML)">Normal link</a>
</div>

<button type="button" onclick="fakeClick(event, document.getElementById('link'))">
  Fake Click on Normal Link
</button>

<br /><br />

<div onclick="alert('Container clicked')">
    <div onclick="fakeClick(event, this.getElementsByTagName('a')[0])"><a id="link2" href="#" onclick="alert('foo')">Embedded Link</a></div>
</div>

<button type="button" onclick="fakeClick(event, document.getElementById('link2'))">Fake Click on Embedded Link</button>

</body>
</html>

Demo here.

在这里演示。

It avoids recursion in non-IE browsers by inspecting the event object that is initiating the simulated click, by inspecting the target attribute of the event (which remains unchanged during propagation).

它通过检查事件的目标属性(在传播期间保持不变)来检查启动模拟点击的事件对象,从而避免非IE浏览器中的递归。

Obviously IE does this internally holding a reference to its global event object. DOM level 2 defines no such global variable, so for that reason the simulator must pass in its local copy of event.

IE显然在内部持有对其全局事件对象的引用。 DOM级别2没有定义这样的全局变量,因此模拟器必须传入其本地事件副本。

#2


11  

well, you can very quickly test the click dispatch via jQuery like so

好吧,你可以通过jQuery快速测试点击调度

$('#link-id').click();

If you're still having problem with click respecting the target, you can always do this

如果您仍然遇到点击尊重目标的问题,您可以随时执行此操作

$('#link-id').click( function( event, anchor )
{
  window.open( anchor.href, anchor.target, '' );
  event.preventDefault();
  return false;
});

#3


11  

Quoted from https://developer.mozilla.org/en/DOM/element.click

引用自https://developer.mozilla.org/en/DOM/element.click

The click method is intended to be used with INPUT elements of type button, checkbox, radio, reset or submit. Gecko does not implement the click method on other elements that might be expected to respond to mouse–clicks such as links (A elements), nor will it necessarily fire the click event of other elements.

click方法旨在与按钮,复选框,无线电,重置或提交类型的INPUT元素一起使用。 Gecko没有对可能期望响应鼠标点击的其他元素(如链接(A元素))实现click方法,也不会触发其他元素的click事件。

Non–Gecko DOMs may behave differently.

非Gecko DOM可能表现不同。

Unfortunately it sounds like you have already discovered the best solution to your problem.

不幸的是,听起来您已经发现了解决问题的最佳方案。

As a side note, I agree that your solution seems less than ideal, but if you encapsulate the functionality inside a method (much like JQuery would do) it is not so bad.

作为旁注,我同意你的解决方案似乎不太理想,但如果你将一个功能封装在一个方法中(就像JQuery会做的那样),那就不那么糟了。

#4


4  

There is a simpler way to achieve it,

有一种更简单的方法来实现它,

HTML

HTML

<a href="https://getbootstrap.com/" id="fooLinkID" target="_blank">Bootstrap is life !</a>

JavaScript

JavaScript的

// Simulating click after 3 seconds
setTimeout(function(){
  document.getElementById('fooLinkID').click();
}, 3 * 1000);

Using plain javascript to simulate a click along with addressing the target property.

使用普通的javascript来模拟点击以及寻址目标属性。

You can check working example here on jsFiddle.

您可以在jsFiddle上查看这里的工作示例。

#5


0  

None of the above solutions address the generic intention of the original request. What if we don't know the id of the anchor? What if it doesn't have an id? What if it doesn't even have an href parameter (e.g. prev/next icon in a carousel)? What if we want to apply the action to multiple anchors with different models in an agnostic fashion? Here's an example that does something instead of a click, then later simulates the click (for any anchor or other tag):

上述解决方案均未解决原始请求的一般意图。如果我们不知道锚点的id怎么办?如果它没有id怎么办?如果它甚至没有href参数(例如旋转木马中的上一个/下一个图标)怎么办?如果我们想以不可知的方式将动作应用于具有不同模型的多个锚点,该怎么办?这是一个做一些事情而不是点击的例子,然后模拟点击(对于任何锚点或其他标签):

var clicker = null;
$('a').click(function(e){ 
    clicker=$(this); // capture the clicked dom object
    /* ... do something ... */
    e.preventDefault(); // prevent original click action
});
clicker[0].click(); // this repeats the original click. [0] is necessary.