2012-06-05 14 views
12

In JavaScript-Code möchte ich programmgesteuert den Browser einem Link folgen, der auf meiner Seite ist. Einfacher Fall:Javascript/jQuery: programmatisch folgen Sie einem Link

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

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

Dies ist hypothetisch, da es nicht wirklich funktioniert. Und nein, Triggerung click tut es nicht.

Ich bin mir bewusst, window.location und window.open aber diese unterscheiden sich von nativen Link-Anschluss in gewisser Weise, die mir wichtig: a) in Gegenwart eines <base /> Element, und b) im Falle von mailto URLs. Letzteres ist insbesondere bedeutsam. Zumindest in Firefox ruft der Aufruf window.location.href = "mailto:[email protected]" die unload Handler des Fensters auf, während das Anklicken eines mailto Links nicht funktioniert, soweit ich das beurteilen kann.

Ich bin auf der Suche nach einer Möglichkeit, die Browser-Standardbehandlung von Links aus Javascript-Code auszulösen.

Gibt es einen solchen Mechanismus? Toolkit-spezifische Antworten sind ebenfalls willkommen (speziell für Gecko).

+0

Warum nicht einfach ein Attribut target = "_ blank" in Ihrem mailto: link verwenden? –

+0

kann ich, aber das lässt ein leeres Fenster offen, während ohne dass mein Mail-Client öffnet, aber mein Browser bleibt wie es ist, was ich will. – Dan

+0

Ihre jsFiddle Beispiele funktionieren für mich mit Firefox Aurora 14.0a2 (2012-06-04). –

Antwort

17

Soweit ich weiß, window.location genau das tut, was Sie suchen, und löst die Standard Link Browser Verhalten.

Einige Browser bemerken das Protokoll bevor irgendwelche Ereignisse ausgelöst werden oder die tatsächliche href geändert wird.

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

die Geige Demo unten erhalte ich folgende Ergebnisse erwähnt Versuch:

  • Chrom: Feuer onbeforeunload mit dem Button und Link
  • Firefox feuert onbeforeunload nur für die Schaltfläche
  • Safari: nie Brände onbeforeunload
  • Opera: wie Safari

So eine gute Möglichkeit zu verhindern, dass das unload Ereignis ausgelöst wird, ist durch die Rückgabe false in beforeunload.

+0

Nein, nicht ganz dasselbe. Siehe http://jsfiddle.net/eyS6x/2/. "Click me" ruft den 'beforeunload'-Handler auf, der Link selbst nicht. – Dan

+0

Fair genug, ich habe dies jetzt in mehreren Browsern getestet und es scheint Verhalten ist ganz anders. Ich werde meine Antwort aktualisieren, um dies zu reflektieren. –

+0

Nun, vielleicht hast du hier etwas vor. In meinem echten Code ist es _only_ 'beforeunload' und nicht' unload' das ich habe. Das habe ich in meinem OP versaut. Gibt es einen Weg _inside_ mein 'beforeunload' Handler, den ich erkennen kann, ob es ein mailto ist? – Dan

3

METHODE 1 Klick-Methode

HTMLElement s haben eine Methode click()https://developer.mozilla.org/en/DOM/element.click

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

Methode 2 Firing synthetische Ereignisse

Ich frage mich, warum saluce seine Antwort gelöscht. Diese Lösung ist, was ich in der Vergangenheit verwendet habe (als Klick war ein IE nur Sache). Das heißt, ein synthetisches Browserereignis auslösen (nicht eine falsche wie jQuery click()). Lassen Sie mich eine Lösung veröffentlichen diese Idee mit ...

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 .... Ich dachte, ich habe das ausprobiert und es hat nicht funktioniert. Lass mich es nochmal versuchen. – Dan

+0

Tatsächlich tut es nicht. Versuchen Sie http://jsfiddle.net/eyS6x/1/ und klicken Sie auf "Click Me". Dies ist in Firefox 5.0 für MacOS. – Dan

+1

Es funktioniert auf Chrome (19.0.1084.52 m), Firefox (10.0.3) und IE (8.0.7600) unter Windows. Es könnte ein Mac-Problem sein. –

Verwandte Themen