web-dev-qa-db-fra.com

Comment puis-je invoquer par programme un événement onclick () à partir d’une balise ancre tout en conservant la référence "this" dans la fonction onclick?

Ce qui suit ne fonctionne pas ... (du moins pas dans Firefox: document.getElementById('linkid').click() 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>
78
Ropstah

Vous devez apply le gestionnaire d’événements dans le contexte de cet élément:

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

Sinon, this ferait référence au contexte dans lequel le code ci-dessus est exécuté.

105
Gumbo

La meilleure façon de résoudre ce problème est d’utiliser Vanilla JS, mais si vous utilisez déjà jQuery, il existe une solution très simple:

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

18
luschn

Pour déclencher un événement, vous appelez simplement le gestionnaire d'événements pour cet élément. Léger changement de votre code.

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

if (typeof(evnt) == "function") {
    evnt.call(a);
}
15
simplyharsh
$("#linkid").trigger("click");
5
guest

Certes, OP a déclaré de manière très similaire que cela ne fonctionnait pas, mais que cela fonctionnait pour moi. D'après les notes de ma source, il semble que cela ait été mis en œuvre à peu près au moment ou après le post de OP. Peut-être que c'est plus standard maintenant.

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

Dans mon cas, mon bouton n'avait pas d'identifiant. Si votre élément a un identifiant, utilisez de préférence le code suivant (non testé).

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

J'ai initialement essayé cette méthode et cela n'a pas fonctionné. Après avoir cherché sur Google, je suis revenu et j'ai réalisé que mon élément était nommé et que je n'avais pas d'identifiant. Vérifiez que vous appelez le bon attribut.

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

2
Tyler Montney

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

Maintenant, cliquez sur votre élément (avec l'id "myElement") et il devrait imprimer ce qui suit dans la console:

événement attrapé: clic
ABC

Cela vous permet d'avoir une méthode d'objet en tant que gestionnaire d'événements et d'avoir accès à toutes les propriétés d'objet de cette méthode.

Vous ne pouvez pas simplement passer une méthode d'un objet à addEventListener directement (comme ça: element.addEventListener('click',myObj.myMethod);) et attendre myMethod pour agir comme si j'étais normalement appelé sur l'objet. Je suppose que toute fonction transmise à addEventListener est en quelque sorte copiée au lieu d'être référencée. Par exemple, si vous transmettez une référence de fonction d'écouteur d'événements à addEventListener (sous la forme d'une variable), puis désactivez cette référence, l'écouteur d'événements est toujours exécuté lorsque les événements sont interceptés.

Une autre solution de contournement (moins élégante) pour passer une méthode en tant qu'écouteur d'événement et stil this tout en ayant accès aux propriétés de l'objet dans l'écouteur d'événement serait quelque chose du genre:

// see above for definition of MyObj

var myObj = new MyObj();

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

Vieux fil, mais la question est toujours d'actualité, alors ...

(1) L'exemple de votre question maintenant NE fonctionne dans Firefox. Cependant, en plus d'appeler le gestionnaire d'événements (qui affiche une alerte), il ET AUSSI clique sur le lien, ce qui entraîne la navigation (une fois l'alerte supprimée).

(2) Pour SIMPLEMENT appeler le gestionnaire d'événements (sans déclencher la navigation), remplace simplement:

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

avec

document.getElementById('linkid').onclick();
0
Doin

Si vous utilisez ceci uniquement pour référencer 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érerais 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 souhaitez appeler la même fonction à partir d'un autre code javascript, simuler un clic pour appeler la fonction n'est pas la meilleure solution. Considérer:

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