Come posso richiamare un livello di codice) evento (onclick da un tag di ancoraggio, mantenendo il ‘questo’ riferimento nella funzione onclick?

StackOverflow https://stackoverflow.com/questions/906486

  •  05-09-2019
  •  | 
  •  

Domanda

Di seguito non funziona ... (almeno non in Firefox: document.getElementById('linkid').click() non è una funzione)

<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>
È stato utile?

Soluzione

È necessario apply il gestore di eventi nel contesto di tale elemento:

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

Altrimenti sarebbe this riferimento contesto codice precedente viene eseguito in.

Altri suggerimenti

Il modo migliore per risolvere questo è quello di utilizzare Vanilla JS, ma se si sta già utilizzando jQuery, Theres una soluzione molto semplice:

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

Testato in IE8-10, Chrome, Firefox.

Per attivare un evento che, fondamentalmente, basta chiamare il gestore di eventi per questo elemento. Leggero cambiamento dal codice.

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

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

Certo, OP ha dichiarato in modo molto simile che questo non ha funzionato, ma lo ha fatto per me. Sulla base delle note a mia fonte, a quanto pare è stato implementato in tutto il tempo, o dopo, post di OP. Forse è più standard ora.

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

Nel mio caso, il mio tasto non ha avuto un ID. Se il vostro elemento ha un id, preferibilmente utilizzare la seguente (non testato).

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

Originariamente ho provato questo metodo e non ha funzionato. Dopo Googling sono tornato e realizzato il mio elemento è stato per nome, e non hanno un ID. Doppio controllo che si sta chiamando l'attributo destra.

Fonte: https://developer.mozilla.org / it-IT / docs / Web / API / HTMLElement / click

Date un'occhiata al metodo 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);

Ora cliccate sul vostro elemento (con id "MyElement") e dovrebbe stampare il seguente nella console:

  

evento catturato: clicca
  ABC

Questo permette di avere un metodo di oggetto come gestore di eventi, e avere accesso a tutte le proprietà degli oggetti di quel metodo.

non possono semplicemente passare un metodo di un oggetto a addEventListener direttamente (come quella: element.addEventListener('click',myObj.myMethod);) e si aspettano myMethod di agire come se fossi normalmente chiamato sull'oggetto. Sto indovinando che qualsiasi funzione passata a addEventListener è in qualche modo copiato invece di essere riferimento. Ad esempio, se si passa una funzione listener evento di riferimento a addEventListener (sotto forma di una variabile) quindi Annulla questo riferimento, l'ascoltatore evento viene comunque eseguito quando gli eventi sono catturati.

Un altro (meno elegante) soluzione per passare un metodo listener di eventi e this stil e hanno ancora accesso alle proprietà degli oggetti all'interno del listener di eventi sarebbe qualcosa di simile:

// see above for definition of MyObj

var myObj = new MyObj();

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

Se stai usando questo puramente per fare riferimento alla funzione l'attributo onclick, questa sembra una pessima idea. gli eventi in linea sono una cattiva idea in generale.

Vorrei suggerire il seguente:

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

Se si desidera chiamare la stessa funzione da altro codice javascript, simulando un clic per chiamare la funzione non è il modo migliore. Prendere in considerazione:

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

Old filo, ma la questione è ancora attuale, in modo da ...

(1) L'esempio nella tua domanda ora Il lavoro in Firefox. Tuttavia, oltre a chiamare il gestore di eventi (che visualizza un avviso), ma ANCHE fa clic sul link, causando la navigazione (una volta che l'allarme è respinto).

(2) Per SOLO chiamare il gestore di eventi (senza attivare la navigazione) semplicemente sostituire:

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

con

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

In generale lo consiglio contro chiamando i gestori di eventi 'manualmente'.

  • Non è chiaro ciò che viene eseguito a causa di molteplici registrata ascoltatori
  • Pericolo per entrare in un evento-ciclo ricorsivo e infinito (fare clic su un innescando Clicca B, innescando click A, ecc.)
  • aggiornamenti ridondanti per il DOM
  • difficile distinguere i cambiamenti effettivi nella vista causati dall'utente da modifiche apportate come codice di inizializzazione (che dovrebbe essere eseguito solo una volta).

È meglio per capire che cosa esattamente si desidera avere accadere, che mettere in una funzione e chiamare che manualmente e registrarlo come listener di eventi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top