本文介绍了如何模拟对锚标记的点击?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想模拟对锚标记的点击,以及正确的目标处理等所有附加功能.

锚的 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,但我不确定它处理目标属性的效果如何,因为我以前没有使用过它.

解决方案

这是一个完整的测试用例,它模拟 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"><头><脚本>函数fakeClick(事件,anchorObj){如果(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);//您可以检查 allowDefault 为 false 以查看是否//任何名为 evt.preventDefault() 的处理程序.//Firefox *不会*重定向到anchorObj.href//为你.但是,其他所有浏览器都会.}}}<身体><div onclick="alert('Container clicked')"><a id="link" href="#" onclick="alert((event.target || event.srcElement).innerHTML)">普通链接</a>

<button type="button" onclick="fakeClick(event, document.getElementById('link'))">假点击正常链接<br/><br/><div onclick="alert('Container clicked')"><div onclick="fakeClick(event, this.getElementsByTagName('a')[0])"><a id="link2" href="#" onclick="alert('foo')">嵌入式链接

<button type="button" onclick="fakeClick(event, document.getElementById('link2'))">假点击嵌入式链接</button>

此处演示.

通过检查事件的 target 属性(在传播过程中保持不变).

显然 IE 会在内部执行此操作,并持有对其 全局event 对象.DOM 级别 2 没有定义这样的全局变量,因此模拟器必须传入它的 event 本地副本.

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:

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.

I found this alternate solution for Firefox in Mozilla forums:

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.

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.

解决方案

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

<!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).

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.

这篇关于如何模拟对锚标记的点击?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 16:13