2009-03-31 28 views
21

Ich möchte, dass der Browser so verhält, als hätte der Benutzer die Tabulatortaste gedrückt, wenn er auf etwas klickt. Im Click-Handler habe ich folgende Ansätze versucht:Tabulatortaste mit JavaScript simulieren

var event = document.createEvent('KeyboardEvent'); 
event.initKeyEvent("keypress", true, true, null, false, false, false, false, 9, 0); 
this.input.focus()[0].dispatchEvent(event); 

Und jQuery:

this.input.focus().trigger({ type : 'keypress', which : 9 }); 

..., die ich von here nahm.

Der erste Ansatz scheint die beste Wette zu sein, funktioniert aber nicht ganz. Wenn ich die letzten beiden Parameter auf 98, 98 ändere, wird tatsächlich ein 'b' in das Eingabefeld eingegeben. Aber 9, 0 und 9, 9 (von denen das erstere nahm ich direkt von der MDC-Website), die beide geben mir diese Fehler in Firebug unter FF3:

Permission denied to get property XULElement.popupOpen 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

Permission denied to get property XULElement.overrideValue 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

Permission denied to get property XULElement.selectedIndex 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

Permission denied to set property XULElement.selectedIndex 
[Break on this error] this.input.focus()[0].dispatchEvent(event); 

Ich habe so gehört (ohne klare Definition des Begriffs "solche" Ereignisse sind "nicht vertrauenswürdig", was diese Fehler erklären könnte. Der zweite Ansatz verursacht jeden Wert, den ich als event.which setze, was als event.which übergeben wird, aber ohne Wirkung (auch wenn ich 98 anstelle von 9 verwende, wird in der Box kein 'b' eingegeben). If Ich versuche, event.data in dem Objekt, das ich überlasse, zu setzen, es endet undefiniert, wenn das Ereignis ausgelöst wird. Was folgt ist der Code, den ich verwende, um das anzuzeigen:

$('#hi').keypress(function(e) { 
    console.log(e); 
}); 

Irgendwelche anderen Ideen?

+0

Was möchten Sie aufrufen? Versuchen Sie, sie zur nächsten Eingabe zu bewegen? – hunter

+0

Ja. Aber die nächste "Eingabe" ist nicht notwendigerweise eine Eingabe oder ein anderes natürlich tabstopped Element. Es ist auch nicht notwendigerweise unnatürlich-tabstopped (d. H. $ ("[Tabindex]")). Drücken Sie die Tabulatortaste (oder Shift + Tab) genau das, was ich will ... – Kev

+0

Danke dafür. Ich war nur am ersten Codebeispiel Ihrer Frage interessiert, das wirklich geholfen hat :) –

Antwort

4

Die Lösung, mit der ich endete, ist, einen "Fokus-Stealer" div zu erstellen (mit Tabindex = -1 - kann den Fokus haben, kann aber nicht initialisiert werden) auf beiden Seiten des Bereichs, in dem ich möchte den Fokus manuell verwalten. Dann platziere ich einen blubbernden Event-Listener für Fokus und Unschärfe auf der ganzen Fläche. Wenn in dem Bereich ein Fokus auftritt, werden die Tabindexwerte in -1 geändert, und wenn eine Unschärfe auftritt, werden sie in 0 geändert. Dies bedeutet, dass Sie, während Sie im Bereich fokussiert sind, Tabs oder Shift-Tabs daraus ziehen können korrekt auf anderen Seitenelementen oder Browser-UI-Elementen landen, aber sobald Sie sich von dort aus fokussieren, werden die Fokus-Stealer tabellarisch, und im Fokus richten sie den manuellen Bereich korrekt ein und lenken den Fokus auf das Element an ihrem Ende, als ob Sie auf das eine oder andere Ende des manuellen Bereichs geklickt hätten.

1

Eigentlich denke ich, es gibt einen Weg, auch wenn es eine große PITA ist. Ich kann sicherstellen, dass jedes Element, auch wenn es natürlich ein Tab-Stop ist, einen Xtabindex hat, irgendwie in der richtigen Reihenfolge, auch wenn ich die Widgets anderer Leute benutze und jQuery verwende, um diese nachträglich hinzuzufügen, anstatt es zu sein in der Lage, es direkt im HTML- oder anderen anfänglichen Baucode anzugeben. Dann wird meine gesamte Form einen echten Tabindex haben. Während es den Fokus hat, absorbiert es Tastendrucke, und wenn sie Tab oder Shift + Tab sind, verschieben Sie den falschen Fokus basierend auf Xtabindex. Wenn die Tabulatortaste auf dem letzten (oder Shift + Tab auf dem ersten) Element des Formulars gedrückt wird, wird der Tastendruck nicht verschlungen und der Browser kann sich mit der Tastatur auf andere Seiten- oder Browser-UI-Elemente außerhalb des Formulars konzentrieren.

Ich kann nur raten, welche Arten von unbeabsichtigten Nebenwirkungen dieser Ansatz einführen wird.

Eigentlich ist es nicht einmal eine Lösung, weil ich immer noch nicht eine Registerkarte auf das letzte Element fälschen kann.

+0

http: // lists .whatwg.org/htdig.cgi/whatwg-whatwg.org/2008-December/017980.html brachte einen interessanten Punkt auf den Punkt: "Aber was ist, wenn der Benutzeragent nicht mit einem Zyklus arbeitet, sondern stattdessen das Directional Focus Management verwendet? , wie viele Telefone? " – Kev

3

Dies ist die Lösung, die ich für zwei benutzerdefinierte Steuerelemente auf unsere Webapp verwendet, ein Pop-up-Kalender und ein Pop-up-Einheit/Wert Gewichtungsselektor (das Textfeld klicken, ein Div mit zwei wählt erscheint)

function tab_focus(elem) 
    var fields = elem.form.getElements() 
    for(var i=0;i<fields.length;i++) { 
    if(fields[i].id == elem.id){ 
     for(i=i+1;i<fields.length;i++){ 
     if(fields[i].type != 'hidden'){ 
      fields[i].focus() 
      return  
     } 
     } 
     break; 
    } 
    } 
    elem.form.focusFirstElement(); 
} 

Dies verwendet das Prototype-Framework und erwartet ein erweitertes Element (dh $ ('thing_id')) als Parameter.

Es erhält die Form, zu der das Element gehört, und durchläuft die Elemente der Form, bis es sich selbst findet.

Es sucht dann nach dem ersten Element, das nicht versteckt ist, und übergibt es den Fokus.

Wenn sich im Formular keine Elemente befinden, wird der Fokus auf das erste Element im Formular verschoben. Ich könnte stattdessen das nächste Formular auf der Seite über document.forms finden, aber die meisten unserer Seiten verwenden ein einzelnes Formular.

+0

Die Sache ist, einige meiner fokussierbaren UI-Elemente sind keine Formularelemente, weil sie benutzerdefinierte Widgets sind. – Kev

+1

Ersetzen Sie für jquery-Benutzer die erste Zeile dieser Funktion durch: var fields = $ ('form') [0]; Um die Formularelemente zu durchlaufen. – eniac

0

Ich denke, dass diese Fehler von der automatischen Vervollständigung sind. Sie könnten in der Lage sein, sie durch Setzen, bevor Sie das -Ereignis, das die automatische Vervollständigung Attribut auf ‚off‘

setAttribute('autocomplete','off') 
1

Ich habe eine simple jQuery plugin, die löst dieses Problem auszuschalten. Es verwendet den ': tabbable' Selektor von jQuery UI, um das nächste 'tabbable' Element zu finden und wählt es aus.

Beispiel Nutzung:

// Simulate tab key when element is clicked 
$('.myElement').bind('click', function(event){ 
    $.tabNext(); 
    return false; 
}); 
Verwandte Themen