Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
188 views
in Technique[技术] by (71.8m points)

javascript - How can I simulate a click to an anchor tag?

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:

Error: anchorObj.click is not a function

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.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...