2009-09-14 16 views
43

Quiero simular un clic en una etiqueta de anclaje con todos los extras, como el manejo correcto del objetivo.¿Cómo puedo simular un clic en una etiqueta de anclaje?

Parece haber un método "[clic()] [3]" para el objeto DOM del ancla, pero no todos los navegadores lo admiten. Firefox lanza este error:

Error: anchorObj.click is not a function

También funciona extrañamente en Opera 10 y Konqueror, haciendo clics infinitas a pasar cuando se llama dentro del manejador onclick de un div rodea. Supongo que solo IE8 funciona bien con eso. De todos modos, no lo quiero, ya que los navegadores principales en su mayoría tienen problemas con él.

He encontrado esta solución alternativa para Firefox en los foros de Mozilla:

var evt = document.createEvent("MouseEvents"); 
evt.initMouseEvent("click", true, true, window, 
    0, 0, 0, 0, 0, false, false, false, false, 0, null); 
anchorObj.dispatchEvent(evt); 

Esto parece demasiado feo e incómodo para mí. No sé qué tan compatible es y quiero evitar escribir el código específico del navegador tanto como sea posible.

No puedo usar location.href = anchorObj.href; porque no maneja el atributo "objetivo". Puedo hacer una codificación difícil en función del valor del objetivo, pero me gustaría evitar eso también.

Hay una sugerencia de cambiar a JQuery, pero no estoy seguro de qué tan bien maneja la propiedad de destino, ya que no he trabajado con ella antes.

+0

Posible duplicado de [JavaScript: invocación de click-event de una etiqueta ancla desde javascript] (http://stackoverflow.com/questions/980709/javascript-invoking-click-event-of-an-anchor-tag-from -javascript) –

Respuesta

61

Aquí es un caso de prueba completa que simula el evento click, llama a todos los controladores conectados (sin embargo, se han adjuntado), mantiene el atributo "target" ("srcElement" en IE), burbujas como un evento normal haría, y emula recursion- de IE prevención. Probado de FF 2, Chrome 2.0, Opera 9.10 y por supuesto IE (6):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<script> 
function fakeClick(event, anchorObj) { 
    if (anchorObj.click) { 
    anchorObj.click() 
    } else if(document.createEvent) { 
    if(event.target !== anchorObj) { 
     var evt = document.createEvent("MouseEvents"); 
     evt.initMouseEvent("click", true, true, window, 
      0, 0, 0, 0, 0, false, false, false, false, 0, null); 
     var allowDefault = anchorObj.dispatchEvent(evt); 
     // you can check allowDefault for false to see if 
     // any handler called evt.preventDefault(). 
     // Firefox will *not* redirect to anchorObj.href 
     // for you. However every other browser will. 
    } 
    } 
} 
</script> 
</head> 
<body> 

<div onclick="alert('Container clicked')"> 
    <a id="link" href="#" onclick="alert((event.target || event.srcElement).innerHTML)">Normal link</a> 
</div> 

<button type="button" onclick="fakeClick(event, document.getElementById('link'))"> 
    Fake Click on Normal Link 
</button> 

<br /><br /> 

<div onclick="alert('Container clicked')"> 
    <div onclick="fakeClick(event, this.getElementsByTagName('a')[0])"><a id="link2" href="#" onclick="alert('foo')">Embedded Link</a></div> 
</div> 

<button type="button" onclick="fakeClick(event, document.getElementById('link2'))">Fake Click on Embedded Link</button> 

</body> 
</html> 

Demo here.

Evita recursión en los navegadores no-IE mediante la inspección del objeto de evento que inicia el clic simulado, inspeccionando el atributo target del evento (que remains unchanged during propagation).

Obviamente, IE hace esto internamente con una referencia a su global event object. DOM nivel 2 no define ninguna variable global, por lo que el simulador debe pasar en su copia local de event.

+0

Una actualización: a partir de ahora, initMouseEvent está en desuso, vea [https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent](https://developer.mozilla.org/ en-US/docs/Web/API/MouseEvent/initMouseEvent) use eventos personalizados en su lugar [https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events](https://developer. mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) – user2315552

11

bien, puede probar muy rápidamente el clic de despacho a través de jQuery al igual que

$('#link-id').click(); 

Si sigue teniendo un problema con click respetando el objetivo, siempre se puede hacer esto

$('#link-id').click(function(event, anchor) 
{ 
    window.open(anchor.href, anchor.target, ''); 
    event.preventDefault(); 
    return false; 
}); 
11

citado de https://developer.mozilla.org/en/DOM/element.click

The click method is intended to be used with INPUT elements of type button, checkbox, radio, reset or submit. Gecko does not implement the click method on other elements that might be expected to respond to mouse–clicks such as links (A elements), nor will it necessarily fire the click event of other elements.

Non–Gecko DOMs may behave differently.

Por desgracia, parece que tienes alrea dy descubrió la mejor solución para su problema.

Como nota al margen, estoy de acuerdo en que su solución parece menos que ideal, pero si encapsula la funcionalidad dentro de un método (muy parecido a como lo haría JQuery) no es tan malo.

2

Hay una manera más simple para lograrlo,

HTML

<a href="https://getbootstrap.com/" id="fooLinkID" target="_blank">Bootstrap is life !</a> 

JavaScript

// Simulating click after 3 seconds 
setTimeout(function(){ 
    document.getElementById('fooLinkID').click(); 
}, 3 * 1000); 

uso de JavaScript sencillo para simular un clic, junto con abordar la propiedad de destino .

Puede verificar el ejemplo de trabajo aquí en jsFiddle.

Cuestiones relacionadas