2012-06-05 2 views
12

Nel codice Javascript, vorrei che il browser seguisse a livello di codice un link che si trova sulla mia pagina. Caso semplice:Javascript/jQuery: a livello di codice seguire un collegamento

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

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

Questo è ipotetica in quanto in realtà non funziona. E no, l'attivazione di click non lo fa.

Sono consapevole window.location e window.open ma queste differiscono da nativo collegamento seguente in qualche modo che sono importanti per me: a) in presenza di un elemento <base />, e b) nel caso di mailto URL. Quest'ultimo in particolare è significativo. Almeno in Firefox, chiamando lo window.location.href = "mailto:[email protected]" si attivano i gestori unload della finestra, mentre semplicemente facendo clic su un collegamento mailto, per quanto ne so io.

Sto cercando un modo per attivare la gestione predefinita dei collegamenti del browser, dal codice Javascript.

Esiste un tale meccanismo? Anche le risposte specifiche del toolkit sono benvenute (specialmente per Gecko).

+0

perché non utilizzare solo un attributo target = "_ blank" nel tuo mailto: link? –

+0

Posso, ma lascia aperta una finestra vuota, mentre senza il mio client di posta si apre ma il mio browser rimane così com'è, che è quello che voglio. – Dan

+0

I tuoi esempi jsFiddle funzionano per me con Firefox Aurora 14.0a2 (2012-06-04). –

risposta

17

Per quanto ne so, window.location fa esattamente quello che stai cercando, innescando cliccando sul link di default del browser comportamento.

Alcuni browser notano il protocollo prima che venga generato un evento o che venga modificato l'href effettivo.

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

Provando la demo violino menzionato di seguito ottengo i seguenti risultati:

  • Cromo: incendi onbeforeunload con il pulsante e il collegamento
  • Firefox spara onbeforeunload solo per il pulsante
  • Safari: mai fuochi onbeforeunload
  • Opera: uguale a Safari

Un modo valido per impedire l'attivazione dell'evento unload consiste nel restituire false in beforeunload.

+0

No, non proprio la stessa cosa. Vedi http://jsfiddle.net/eyS6x/2/. "Click me" chiama il gestore 'beforeunload', il collegamento stesso no. – Dan

+0

Abbastanza buono, l'ho testato su più browser ora e sembra che il comportamento sia molto diverso. Aggiornerò la mia risposta per riflettere questo –

+0

Beh, potresti essere coinvolto in qualcosa qui. Nel mio codice reale è _only_ 'beforeunload' e non' scarichi' quello che ho. L'ho incasinato nel mio OP. C'è un modo _inside_ mio 'beforeunload' handler che posso rilevare se si tratta di un mailto? – Dan

3

METODO 1 click metodo

HTMLElement s hanno un metodo click()https://developer.mozilla.org/en/DOM/element.click

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

Metodo 2 Firing eventi sintetici

Mi chiedo perché saluce cancellato la sua risposta. Quella soluzione è ciò che ho usato in passato (quando il clic era una cosa solo IE). Cioè, licenziando un evento sintetico del browser (non un falso come click() di jQuery). Permettetemi di postare una soluzione che utilizza l'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 .... pensavo di averlo provato e non ha funzionato. Fammi riprovare. – Dan

+0

In effetti non è così. Prova http://jsfiddle.net/eyS6x/1/ e fai clic su "Click Me". Questo è in Firefox 5.0 per MacOS. – Dan

+1

Funziona su Chrome (19.0.1084.52 m), Firefox (10.0.3) e IE (8.0.7600) su Windows. Potrebbe essere un problema con il Mac. –