2009-09-14 4 views
43

Je veux simuler un clic sur une balise d'ancrage avec tous les extras comme la manipulation correcte de la cible.Comment puis-je simuler un clic sur une balise d'ancrage?

Il semble qu'il existe une méthode "[click()] [3]" pour l'objet DOM de l'ancre, mais tous les navigateurs ne la prennent pas en charge. Firefox lance cette erreur:

Error: anchorObj.click is not a function

Il fonctionne aussi étrangement sur Opera 10 et Konqueror, ce qui produit des infinies de se produire quand il est appelé à l'intérieur d'un gestionnaire onclick div entourant. Je suppose que seulement IE8 fonctionne bien avec elle. De toute façon je ne le veux pas car les principaux navigateurs ont surtout des problèmes avec ça.

Je trouve cette solution de rechange pour Firefox Mozilla dans les 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); 

Cela semble trop laid et lourd pour moi. Je ne sais pas comment c'est compatible et je veux éviter d'écrire le code spécifique au navigateur autant que possible.

Je ne peux pas utiliser location.href = anchorObj.href; car il ne gère pas l'attribut "target". Je peux faire du codage en fonction de la valeur de la cible, mais j'aimerais aussi éviter cela.

Il est suggéré de passer à JQuery, mais je ne suis pas sûr de la façon dont il gère la propriété target, car je ne l'ai pas déjà utilisé auparavant.

+0

Possible duplicata de [JavaScript: Invocation d'un événement click d'un tag d'ancrage de javascript] (http://stackoverflow.com/questions/980709/javascript-invoking-click-event-of-an-anchor-tag-from -javascript) –

Répondre

61

Voici un test complet qui simule l'événement click, appelle tous les gestionnaires attachés (mais ils ont été attachés), maintient l'attribut "target" ("srcElement" dans IE), des bulles comme un événement normal serait, et émule la recursion- IE la prévention. Testé FF 2, Chrome 2.0, Opera 9.10 et bien sûr 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.

Il évite récursivité dans les navigateurs non IE en examinant l'objet d'événement qui lance le clic simulé, en inspectant l'attribut target de l'événement (lequel remains unchanged during propagation).

Évidemment IE fait cela en interne en maintenant une référence à son global event object. Le niveau DOM 2 ne définit pas de telle variable globale, c'est pourquoi le simulateur doit transmettre sa copie locale de event.

+0

Une mise à jour: à partir de maintenant, initMouseEvent est obsolète voir [https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent](https://developer.mozilla.org/ En-US/docs/Web/API/MouseEvent/initMouseEvent) utilisent des événements personnalisés à la place [https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events](https://developer. mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) – user2315552

11

bien, vous pouvez très rapidement tester l'envoi de clic via jQuery comme si

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

Si vous rencontrez toujours un problème, cliquez sur la cible, vous pouvez toujours faire

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

cité de 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.

Non–Gecko DOMs may behave differently.

Malheureusement, il semble que vous avez alrea dy a découvert la meilleure solution à votre problème.

En guise de remarque, je suis d'accord que votre solution semble moins qu'idéale, mais si vous encapsulez la fonctionnalité à l'intérieur d'une méthode (tout comme JQuery le ferait) ce n'est pas si mal.

2

Il y a une façon plus simple pour y parvenir,

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

En utilisant javascript simple pour simuler un clic avec adressage la propriété cible .

Vous pouvez vérifier l'exemple de travail ici sur jsFiddle.

Questions connexes