我想模拟点击一个锚标记,其中包含正确的目标处理等所有额外内容。
对于锚点的DOM对象似乎有一个“[click()] [3]”方法,但并非所有浏览器都支持它。 Firefox抛出此错误:
错误:anchorObj.click不是函数
它在Opera 10和Konqueror上也很奇怪,当它在周围div的onclick处理程序中调用时会导致无限点击。我想只有IE8可以正常使用它。无论如何我不想要它,因为主流浏览器大多数都有问题。
我在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);
这对我来说似乎太丑陋了。我不知道它是多么兼容,我想尽可能避免编写特定于浏览器的代码。
我不能使用location.href = anchorObj.href;因为它不处理“目标”属性。我可以根据目标值进行一些硬编码,但我也想避免这种情况。
有建议切换到JQuery,但我不确定它处理目标属性的能力,因为我之前没有使用它。
答案 0 :(得分:63)
这是一个完整的测试用例,模拟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>
通过检查事件的target
属性(remains unchanged during propagation)来检查启动模拟点击的事件对象,从而避免非IE浏览器中的递归。
显然,IE在内部持有对其global event
object的引用。 DOM级别2没有定义这样的全局变量,因此模拟器必须传入event
的本地副本。
答案 1 :(得分:11)
好吧,你可以通过jQuery快速测试点击调度
$('#link-id').click();
如果您仍然遇到点击尊重目标的问题,您可以随时执行此操作
$('#link-id').click( function( event, anchor )
{
window.open( anchor.href, anchor.target, '' );
event.preventDefault();
return false;
});
答案 2 :(得分:11)
引自https://developer.mozilla.org/en/DOM/element.click
click方法适用于按钮,复选框,广播,重置或提交类型的INPUT元素。 Gecko没有对可能需要响应鼠标点击的其他元素(如链接(A元素))实现click方法,也不会触发其他元素的click事件。
非Gecko DOM可能表现不同。
不幸的是,听起来您已经找到了解决问题的最佳方案。
作为旁注,我同意你的解决方案似乎不太理想,但是如果你在一个方法中封装了这个功能(就像JQuery那样),那就不那么糟了。
答案 3 :(得分:6)
有一种更简单的方法来实现它,
HTML
<a href="https://getbootstrap.com/" id="fooLinkID" target="_blank">Bootstrap is life !</a>
JavaScript
// Simulating click after 3 seconds
setTimeout(function(){
document.getElementById('fooLinkID').click();
}, 3 * 1000);
使用普通的javascript来模拟点击以及寻址目标属性。
您可以在jsFiddle上查看工作示例。
答案 4 :(得分:0)
上述解决方案均未解决原始请求的一般意图。如果我们不知道锚点的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.