Como posso programaticamente invocar um onclick () evento de uma marca de âncora, mantendo o ‘this’ referência na função onclick?

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

  •  05-09-2019
  •  | 
  •  

Pergunta

A seguir não funciona ... (pelo menos não no Firefox: document.getElementById('linkid').click() não é uma função)

<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>
Foi útil?

Solução

Você precisa apply o manipulador de eventos no contexto desse elemento:

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

Caso contrário this faria referência ao contexto, o código acima é executado em.

Outras dicas

A melhor maneira de resolver isso é usar Vanilla JS, mas se você já estiver usando jQuery, há's uma solução muito fácil:

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

Testado em IE8-10, Chrome, Firefox.

Para acionar um evento que você basicamente só chamar o manipulador de eventos para que elemento. Ligeira alteração do seu código.

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

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

Com certeza, OP afirmado de forma muito semelhante que este não funcionou, mas ele fez por mim. Com base nas notas em minha fonte, parece que foi implementado em todo o tempo, ou depois, o post de OP. Talvez seja mais padrão agora.

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

No meu caso, meu botão não tem um ID. Se o seu elemento tem um ID, de preferência use o seguinte (não testado).

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

Inicialmente eu tentei este método e não funcionou. Após Googling eu voltei e percebi que meu elemento era pelo nome, e não tem um ID. verifique que você está chamando o atributo direita.

Fonte: https://developer.mozilla.org / en-US / docs / web / API / HTMLElement / clique

Tenha um olhar para o método 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);

Agora clique no seu elemento (com id "meuElemento") e deve imprimir o seguinte no console:

evento capturado: clique
ABC

Isso permite que você tem um método de objeto como manipulador de eventos, e ter acesso a todas as propriedades do objeto em que o método.

Você não pode apenas passar um método de um objeto para addEventListener diretamente (assim: element.addEventListener('click',myObj.myMethod);) e esperar que myMethod a agir como se eu era normalmente chamado no objeto. Eu estou supondo que qualquer função passado para addEventListener é de alguma forma copiado em vez de ser referenciado. Por exemplo, se você passar uma referência de função de ouvinte de evento para addEventListener (na forma de uma variável), então unset esta referência, o ouvinte de evento ainda é executado quando os eventos são capturados.

Outro (menos elegante) Solução alternativa para passar um método como ouvinte de evento e this stil e ainda ter acesso a propriedades do objeto dentro do ouvinte de evento seria algo assim:

// see above for definition of MyObj

var myObj = new MyObj();

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

Se você estiver usando este puramente para fazer referência a função no atributo onclick, esta parece ser uma idéia muito ruim. eventos em linha são uma má idéia em geral.

Gostaria de sugerir o seguinte:

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 você quiser chamar a mesma função de outro código javascript, simulando um clique para chamar a função não é a melhor maneira. Considere o seguinte:

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

discussão antiga, mas a questão ainda é relevante, então ...

(1) O exemplo na sua pergunta agora O trabalho no Firefox. No entanto, além de chamar o manipulador de eventos (que exibe um alerta), ele TAMBÉM clica no link, causando navegação (uma vez que o alerta é demitido).

(2) APENAS chamar o manipulador de eventos (sem disparar navegação) simplesmente substituir:

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

com

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

Em geral, eu recomendaria contra chamar os manipuladores de eventos 'manualmente'.

  • Não está claro o que é executado por causa de múltiplos registrado ouvintes
  • Perigo para entrar em um evento de circuito recursivo e infinito (clique em Um provocando Click B, provocando clique A, etc.)
  • atualizações redundantes para o DOM
  • difícil distinguir mudanças reais na visão causada pelo usuário de alterações feitas como código de inicialização (que deve ser executado apenas uma vez).

Melhor é para descobrir o que exatamente você quer que aconteça, colocar isso em uma função e chamar isso manualmente e registrá-lo como ouvinte de evento.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top