2012-06-05 17 views
12

En el código Javascript, me gustaría causar que el navegador siga un enlace que está en mi página. Caso sencillo:Javascript/jQuery: siga programáticamente un enlace

<a id="foo" href="mailto:[email protected]">something</a> 

function goToBar() { 
    $('#foo').trigger('follow'); 
} 

Ésta es hipotética, ya que en realidad no funciona. Y no, desencadenar click no lo hace.

Soy consciente de window.location y window.open pero éstas difieren de enlace nativa de seguimiento en algunos aspectos que son importantes para mí: a) en presencia de un elemento de <base />, y b) en el caso de mailto URL. Este último en particular es significativo. En Firefox al menos, llamar al window.location.href = "mailto:[email protected]" hace que se disparen los controladores de la ventana unload, mientras que simplemente hacer clic en un enlace mailto no lo hace, por lo que yo sé.

Estoy buscando una manera de desencadenar el manejo predeterminado del navegador de los enlaces, a partir del código de Javascript.

¿Existe tal mecanismo? Las respuestas específicas de Toolkit también son bienvenidas (especialmente para Gecko).

+0

¿por qué no usar simplemente un atributo target = "_ blank" en su mailto: link? –

+0

Puedo, pero eso deja una ventana en blanco abierta, mientras que sin eso mi cliente de correo se abre pero mi buscador se queda como está, que es lo que quiero. – Dan

+0

Sus ejemplos de jsFiddle funcionan para mí con Firefox Aurora 14.0a2 (2012-06-04). –

Respuesta

17

Por lo que yo sé, window.location hace exactamente lo que busca, lo que provocó predeterminado enlace de clic del navegador comportamiento.

Algunos navegadores notan el protocolo antes de que se activen eventos o se cambie la href real.

window.location = "mailto:[email protected]"; 

Tratar la demo violín se menciona más adelante consigo los siguientes resultados:

  • Cromo: incendios onbeforeunload con el botón y enlace
  • Firefox en los incendios onbeforeunload sólo para el botón
  • Safari: Nunca incendios onbeforeunload
  • Opera: lo mismo que Safari

Así que una buena manera de evitar que se active el evento unload es devolviendo el mensaje falso en beforeunload.

+0

No, no es exactamente lo mismo. Ver http://jsfiddle.net/eyS6x/2/. "Click me" llama al controlador 'beforeunload', el enlace en sí no. – Dan

+0

Bastante, probé esto en múltiples navegadores ahora y parece que el comportamiento es bastante diferente. Actualizaré mi respuesta para reflejar esto. –

+0

Bueno, puede que haya algo aquí. En mi código real, es _only_ 'beforeunload' y no' download' que tengo. Lo arruiné en mi OP. ¿Hay alguna forma de _inside_ my 'beforeunload' handler que pueda detectar si se trata de un mailto? – Dan

3

MÉTODO 1 clic método

HTMLElement s tienen un método click()https://developer.mozilla.org/en/DOM/element.click

function goToBar() { 
    document.getElementById('foo').click(); 
} 

Método 2 arranques sintéticos

Me pregunto por qué saluce borra su respuesta. Esa solución es lo que he usado en el pasado (cuando el clic era solo un IE). Es decir, activar un evento de navegador sintético (no falso como el click() de jQuery). Me deja publicar una solución usar esa idea ...

DEMO: http://jsfiddle.net/eyS6x/3/

/** 
* Fire an event handler to the specified node. Event handlers can detect that the event was fired programatically 
* by testing for a 'synthetic=true' property on the event object 
* @param {HTMLNode} node The node to fire the event handler on. 
* @param {String} eventName The name of the event without the "on" (e.g., "focus") 
*/ 
function fireEvent(node, eventName) { 
    // Make sure we use the ownerDocument from the provided node to avoid cross-window problems 
    var doc; 
    if (node.ownerDocument) { 
    doc = node.ownerDocument; 
    } else if (node.nodeType == 9 /** DOCUMENT_NODE */){ 
    // the node may be the document itself 
    doc = node; 
    } else { 
    throw new Error("Invalid node passed to fireEvent: " + +node.tagName + "#" + node.id); 
    } 

    if (node.fireEvent) { 
    // IE-style 
    var event = doc.createEventObject(); 
    event.synthetic = true; // allow detection of synthetic events 
    node.fireEvent("on" + eventName, event); 
    } else if (node.dispatchEvent) { 
    // Gecko-style approach is much more difficult. 
    var eventClass = ""; 

    // Different events have different event classes. 
    // If this switch statement can't map an eventName to an eventClass, 
    // the event firing is going to fail. 
    switch (eventName) { 
     case "click": 
     case "mousedown": 
     case "mouseup": 
     eventClass = "MouseEvents"; 
     break; 

     case "focus": 
     case "change": 
     case "blur": 
     case "select": 
     eventClass = "HTMLEvents"; 
     break; 

     default: 
     throw "JSUtil.fireEvent: Couldn't find an event class for event '" + eventName + "'."; 
     break; 
    } 
    var event = doc.createEvent(eventClass); 
    var bubbles = eventName == "change" ? false : true; 
    event.initEvent(eventName, bubbles, true); // All events created as bubbling and cancelable. 

    event.synthetic = true; // allow detection of synthetic events 
    node.dispatchEvent(event); 
    } 
}; 

document.getElementById('button').onclick = function() { 
    fireEvent(document.getElementById('link'), 'click'); 
} 
+0

Hm ... Creí haberlo intentado y no funcionó. Déjame intentar de nuevo. – Dan

+0

De hecho, no es así. Pruebe http://jsfiddle.net/eyS6x/1/ y haga clic en "Hacer clic en mí". Esto está en Firefox 5.0 para MacOS. – Dan

+1

Funciona en Chrome (19.0.1084.52 m), Firefox (10.0.3) e IE (8.0.7600) en Windows. Puede ser un problema de Mac. –

Cuestiones relacionadas