2009-05-25 6 views
66

¿Es posible invocar mediante programación un evento onClick para una etiqueta de anclaje, mientras se mantiene la referencia "this" al ancla?¿Cómo puedo invocar programáticamente un evento onclick() desde una etiqueta de anclaje mientras mantengo la referencia 'this' en la función onclick?

El siguiente no funciona ... (al menos no en Firefox:. Document.getElementById ('linkid') haga clic en() no es una función)

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

Respuesta

96

Es necesario apply el controlador de eventos en el contexto de ese elemento:.

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

De lo contrario this haría referencia el contexto del código anterior se ejecuta en

+3

Creo que eres el único que no me ve como un tonto (por no mencionar la notación de corchetes/la incompatibilidad del navegador onclick | click). Spot on! – Ropstah

+2

considere esto: http://www.howtocreate.co.uk/tutorials/javascript/domevents - ¿invocará a la función onclick invoke * todos los controladores de eventos registrados? Además, invocar falsamente un evento no producirá la acción predeterminada asociada con ese evento (por ejemplo, un envío de formulario). – jrharshath

+0

Gumbo, ya que este código produce -diferentes- resultados, todavía no funciona con las bibliotecas Microsoft.Ajax y Microsoft.AjaxMvc .... – Ropstah

15

Para activar un evento que básicamente solo llame al controlador de eventos para ese elemento . Leve cambio de su código.

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

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

+1. Además, un poco de Google revela que foo.click() es solo IE, por supuesto que podría estar equivocado ... – karim79

+0

evnt.onclick() también funcionaría realmente –

+0

Deberías usar la notación de puntos (.onclick) en lugar de con la notación de corchetes (["onclick"]). –

0

Si está usando este puramente para hacer referencia a la función en el atributo onclick, esto parece una idea muy mala. Los eventos en línea son una mala idea en general.

Yo sugeriría lo siguiente:

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 desea llamar a la misma función desde otro código JavaScript, que simula un clic para llamar a la función no es la mejor manera. Considere:

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

se trata de mantener la referencia a 'this'. No puedo generar únicamente la parte onclick en el anclaje (.NET MVC). Necesito generar una etiqueta de ancla completa. Esta etiqueta es requerida completamente por la función onclick (por ejemplo, usa el atributo href). – Ropstah

18

Hay una solución muy fácil con jQuery, acabo de utilizar esto y funciona perfectamente bien:

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

Probado en IE8-10, Chrome, Firefox.

+3

¿por qué el voto a favor? por favor, comenta un motivo, para que pueda mejorar mi pregunta si crees que algo anda mal. – luschn

-1

En general, recomendaría no llamar manualmente a los controladores de eventos.

  • No está claro lo que se ejecuta debido a múltiples registradas oyentes
  • Peligro para entrar en un evento de bucle recursivo e infinito (Haga clic en un activación Haga clic en B, lo que provocó clic A, etc.)
  • redundante actualizaciones del DOM
  • Es difícil distinguir los cambios reales en la vista causados ​​por el usuario de los cambios realizados como código de inicialización (que debe ejecutarse solo una vez).

mejor es averiguar qué es exactamente lo que queremos que suceda, puesto que en una función y llamar a ese manual y registrarlo como detector de eventos.

+0

OP preguntó cómo hacer algo, no cuál es la mejor manera de hacer algo. Esto no es CodeReview. Si hubiera respondido a su pregunta y luego hubiera puesto el descargo de responsabilidad, eso sería diferente. –

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

Bienvenido a SO. ¿Podría explicar en detalle por qué esto funciona (qué es exactamente lo que hace, etc.) y qué lo diferencia de las otras soluciones? – m00am

+1

¿por qué marcar esta respuesta? esta es la mejor solución en esta página si usas jquery ... un forro - ¡no puedo vencer eso! – Hariboo

1

Tenga una mirada en el método handleEvent
https://developer.mozilla.org/en-US/docs/Web/API/EventListener

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

Ahora haga clic en el elemento (con id "myElement") y debe imprimir el siguiendo en la consola:

evento capturado: haga clic en
ABC

Esto le permite tener un método de objeto como controlador de eventos, y tener acceso a todas las propiedades del objeto en ese método.

Usted no puede simplemente pasar un método de un objeto a addEventListener directamente (como esa: element.addEventListener('click',myObj.myMethod);) y esperar que myMethod a actuar como si estuviera normalmente llamado en el objeto. Supongo que cualquier función que se pase a addEventListener se copia de alguna manera en lugar de hacer referencia a ella. Por ejemplo, si pasa una referencia de función de escucha de evento a addEventListener (en forma de una variable) y luego desarma esta referencia, el detector de eventos se sigue ejecutando cuando se capturan eventos.

Otro (menos elegante) solución alternativa para pasar un método como el detector de eventos y stil this y aún así tener acceso a las propiedades de objetos dentro del detector de eventos sería algo así:

// see above for definition of MyObj 

var myObj = new MyObj(); 

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

Por supuesto, OP declaró de manera muy similar que esto no funcionó, pero lo hizo por mí. De acuerdo con las notas en mi fuente, parece que se implementó alrededor del tiempo, o después, de la publicación de OP. Tal vez es más estándar ahora.

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

En mi caso, mi botón no tenía una ID. Si su elemento tiene una identificación, preferiblemente use lo siguiente (no probado).

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

Intenté originalmente este método y no funcionó. Después de buscar en Google, volví y me di cuenta de que mi elemento era por nombre y no tenía una identificación. Verifique que está llamando al atributo correcto.

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

Cuestiones relacionadas