2009-05-25 3 views
66

Est-il possible d'invoquer par programmation un événement onClick pour une balise d'ancrage, tout en conservant la référence «this» à l'ancre?Comment puis-je appeler par programmation un événement onclick() à partir d'un point d'ancrage tout en conservant la référence 'this' dans la fonction onclick?

Ce qui suit ne fonctionne pas ... (au moins pas dans Firefox. Document.getElementById ('de linkid') cliquez sur() n'est pas une fonction)

<script type="text/javascript"> 
    function doOnClick() { 
     document.getElementById('linkid').click(); 
     //Should alert('/testlocation'); 
    } 
</script> 
<a id="linkid" href="/testlocation" onclick="alert(this.href);">Testlink</a> 

Répondre

96

Vous devez apply le gestionnaire d'événements dans le cadre de cet élément.

var elem = document.getElementById("linkid"); 
if (typeof elem.onclick == "function") { 
    elem.onclick.apply(elem); 
} 

Sinon this serait faire référence au contexte, le code ci-dessus est exécuté dans

+3

Je pense que vous êtes le seul à ne pas me voir comme un imbécile (pour ne pas mentionner la notation de parenthèse/l'incompatibilité du navigateur onclick | click). Spot sur! – Ropstah

+2

considérez ceci: http://www.howtocreate.co.uk/tutorials/javascript/domevents - appellera la fonction onclick invoquera * tous * les gestionnaires d'événements enregistrés? De même, invoquer de faussement un événement ne produira pas l'action par défaut associée à cet événement (par exemple, une soumission de formulaire). – jrharshath

+0

Gumbo, car ce code produit des résultats différents, il ne fonctionne toujours pas avec les bibliothèques Microsoft.Ajax et Microsoft.AjaxMvc .... – Ropstah

15

Pour déclencher un événement que vous Il suffit simplement d'appeler le gestionnaire d'événement pour cet élément . Légère modification de votre code.

var a = document.getElementById("element"); 
var evnt = a["onclick"]; 

if (typeof(evnt) == "function") { 
    evnt.call(a); 
} 
+1

+1. En outre, un peu de googling révèle que foo.click() est IE seulement, bien sûr je pourrais me tromper ... – karim79

+0

evnt.onclick() fonctionnerait aussi bien –

+0

Vous devriez utiliser la notation par points (.onclick) plutôt que de avec la notation de parenthèse (["onclick"]). –

0

Si vous utilisez ce uniquement pour faire référence à la fonction dans l'attribut onclick, cela semble être une très mauvaise idée. Les événements en ligne sont une mauvaise idée en général.

Je suggère ce qui suit:

function addEvent(elm, evType, fn, useCapture) { 
    if (elm.addEventListener) { 
     elm.addEventListener(evType, fn, useCapture); 
     return true; 
    } 
    else if (elm.attachEvent) { 
     var r = elm.attachEvent('on' + evType, fn); 
     return r; 
    } 
    else { 
     elm['on' + evType] = fn; 
    } 
} 

handler = function(){ 
    showHref(el); 
} 

showHref = function(el) { 
    alert(el.href); 
} 

var el = document.getElementById('linkid'); 

addEvent(el, 'click', handler); 

Si vous voulez appeler la même fonction d'un autre code javascript, simuler un clic pour appeler la fonction est pas la meilleure façon. Considérez:

function doOnClick() { 
    showHref(document.getElementById('linkid')); 
} 
+0

il s'agit de conserver la référence à 'this'. Je ne peux pas générer uniquement la partie onclick dans l'ancre (.NET MVC). J'ai besoin de générer une balise d'ancrage complète. Cette balise est entièrement requise par la fonction onclick (par exemple, elle utilise l'attribut href). – Ropstah

18

Il y a un solution très facile avec jQuery, je viens de l'utiliser et cela fonctionne parfaitement bien:

<script type="text/javascript"> 
    function doOnClick() { 
     $('#linkid').click(); 
    } 
</script> 
<a id="linkid" href="/testlocation" onclick="alert(this.href);">Testlink</a> 

Testé dans IE8-10, Chrome, Firefox.

+3

pourquoi la downvote? s'il vous plaît commenter une raison, donc je peux améliorer ma question si vous croyez que quelque chose ne va pas. – luschn

-1

En général, je recommande de ne pas appeler manuellement les gestionnaires d'événements.

  • On ne sait pas ce qui est exécuté en raison de multiples enregistrés auditeurs
  • Danger pour entrer dans un événement en boucle récursive et infini (cliquez sur un déclenchement Cliquez sur B, déclenchement cliquez sur A, etc.)
  • redondante mises à jour du DOM
  • Difficile de distinguer les changements réels dans la vue provoqués par l'utilisateur des changements effectués en tant que code d'initialisation (qui ne devrait être exécuté qu'une seule fois).

Mieux vaut savoir exactement ce que vous voulez faire, mettre cela dans une fonction et l'appeler manuellement ET l'enregistrer comme écouteur d'événements.

+0

OP demandé comment faire quelque chose, pas quelle est la meilleure façon de faire quelque chose. Ce n'est pas CodeReview. Si vous aviez répondu à sa question puis mis l'avertissement, ce serait différent. –

4
$("#linkid").trigger("click"); 
+1

Bienvenue sur SO. Pourriez-vous expliquer pourquoi cela fonctionne (que fait-il exactement, etc.) et ce qui le distingue des autres solutions? – m00am

+1

pourquoi marquer cette réponse? C'est la meilleure solution sur cette page si vous utilisez jquery ... un paquebot - ne peux pas battre ça! – Hariboo

1

Jetez un oeil à la méthode handleEvent
https://developer.mozilla.org/en-US/docs/Web/API/EventListener

"Raw" Javascript:

function MyObj() { 
    this.abc = "ABC"; 
} 
MyObj.prototype.handleEvent = function(e) { 
    console.log("caught event: "+e.type); 
    console.log(this.abc); 
} 

var myObj = new MyObj(); 

document.querySelector("#myElement").addEventListener('click', myObj); 

Cliquez maintenant sur votre élément (avec id "myElement") et il devrait imprimer la dans la console:

événement détecté: cliquez sur
ABC

Cela vous permet d'avoir une méthode d'objet comme gestionnaire d'événements, et avoir accès à toutes les propriétés de l'objet dans cette méthode.

Vous ne pouvez pas juste passer une méthode d'un objet à addEventListener directement (comme ça: element.addEventListener('click',myObj.myMethod);) et attendre myMethod à agir comme si je normalement appelé sur l'objet. Je devine que n'importe quelle fonction passée à addEventListener est en quelque sorte copiée au lieu d'être référencée. Par exemple, si vous passez une référence de fonction d'écouteur d'événement à addEventListener (sous la forme d'une variable) puis que vous supprimez cette référence, l'écouteur d'événement est toujours exécuté lorsque des événements sont interceptés.

Une autre (moins élégant) solution pour passer une méthode comme écouteur d'événement et stil this et ont encore accès à des propriétés d'objet dans l'écouteur d'événement serait quelque chose comme ça:

// see above for definition of MyObj 

var myObj = new MyObj(); 

document.querySelector("#myElement").addEventListener('click', myObj.handleEvent.bind(myObj)); 
0

Attribuées, OP a déclaré de façon très similaire que ça n'a pas marché, mais ça a marché pour moi. Basé sur les notes dans ma source, il semble qu'il a été mis en œuvre à peu près au moment, ou après, poste de OP. Peut-être que c'est plus standard maintenant.

document.getElementsByName('MyElementsName')[0].click(); 

Dans mon cas, mon bouton n'avait pas d'ID. Si votre élément a un identifiant, utilisez de préférence les éléments suivants (non testés).

document.getElementById('MyElementsId').click(); 

J'ai d'abord essayé cette méthode et cela n'a pas fonctionné. Après Google, je suis revenu et j'ai réalisé que mon élément était nominatif et n'avait pas de pièce d'identité. Vérifiez que vous appelez le bon attribut.

Source: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click

Questions connexes