it-swarm.com.de

Tabulatortastendruck mit JavaScript simulieren

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

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 hier genommen habe.

Der erste Ansatz scheint der beste zu sein, funktioniert aber nicht ganz. Wenn ich die letzten beiden Parameter in 98, 98 ändere, wird tatsächlich ein 'b' in das Eingabefeld eingegeben. Aber 9, 0 und 9, 9 (die erstere habe ich direkt von der MDC-Website genommen) geben mir beide 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 gehört, dass solche (ohne klare Definition von "solchen") Ereignisse "nicht vertrauenswürdig" sind, was diese Fehler erklären könnte.

Der zweite Ansatz bewirkt, dass der Wert, den ich als event.which angegeben habe, als event.which übergeben wird, aber nicht wirksam wird (auch wenn ich 98 anstelle von 9 verwende, wird kein 'b' in das Feld eingegeben.) Wenn ich versuche, event festzulegen .data in dem Objekt, das ich übergebe, 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?

21
Kev

Die Lösung, die ich letztendlich gewählt habe, besteht darin, auf beiden Seiten des Bereichs, in dem ich manuell verwalten möchte, einen "Fokus-Stealer" -Div (mit tabindex = -1 - kann den Fokus haben, kann aber anfangs nicht mit Tabs versehen werden) zu erstellen der Fokus. Dann habe ich einen sprudelnden, wahren Ereignis-Listener eingerichtet, um den gesamten Bereich zu fokussieren und unscharf zu machen. Wenn ein Fokus auf dem Bereich liegt, werden die Tabulatorindex-Werte in -1 geändert, und wenn Unschärfe auftritt, werden sie in 0 geändert. Dies bedeutet, dass Sie, während Sie auf den Bereich fokussiert sind, einen Tabulator oder einen Shift-Tabulator außerhalb von und verwenden können korrekt auf anderen Seitenelementen oder Browser-UI-Elementen landen, aber sobald Sie sich von dort weg konzentrieren, werden die Fokus-Stealer tabbable und richten den manuellen Bereich korrekt auf Fokus 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.

4
Kev

Dies ist die Lösung, die ich in unserer Webanwendung für zwei benutzerdefinierte Steuerelemente, einen Popup-Kalender und einen Popup-Auswahlschalter für Einheit/Wertgewicht (durch Klicken auf das Textfeld wird ein Div mit zwei Auswahlen angezeigt) verwendet.

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();
}

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

Es ruft die Form ab, zu der das Element gehört, und durchläuft die Elemente des Formulars, bis es sich selbst findet.

Anschließend sucht es nach dem ersten Element, das nicht ausgeblendet ist, und übergibt ihm den Fokus.

Wenn das Formular keine Elemente enthält, wird der Fokus auf das erste Element des Formulars verschoben. Ich konnte stattdessen das nächste Formular auf der Seite über document.forms finden, aber die meisten unserer Seiten verwenden ein einziges Formular.

3
Tilendor

Ich habe ein einfaches jQuery-Plugin erstellt, das dieses Problem löst. Es verwendet den Selektor ': tabbable' der jQuery-Benutzeroberfläche, um das nächste 'tabbable'-Element zu finden und auszuwählen.

Beispielverwendung:

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

Eigentlich denke ich, dass es einen Weg gibt, auch wenn es eine große PITA ist. Ich kann sicherstellen, dass jedes Element, auch wenn es natürlich ein Tabulator ist, einen Xtab-Index hat, und zwar in der richtigen Reihenfolge, auch wenn ich die Widgets anderer Leute lösche und jQuery verwende, um diese nachträglich hinzuzufügen, anstatt zu sein in der Lage, es direkt im HTML-Code oder einem anderen anfänglichen Code anzugeben. Dann wird mein gesamtes Formular einen echten Tabindex haben. Während es den Fokus hat, absorbiert es Tastendrücke. Wenn es sich um Tabulatoren oder Shift + Tabulatoren handelt, verschieben Sie den gefälschten Fokus basierend auf Xtabindex. Wenn die Tabulatortaste auf das letzte (oder die Umschalttaste + Tabulatortaste auf das erste) Element im Formular gedrückt wird, wird der Tastenanschlag nicht blockiert, sodass der Browser sich mit der Tastatur ordnungsgemäß auf andere Seiten- oder Browseroberflächenelemente außerhalb des Formulars konzentrieren kann.

Ich kann nur raten, welche Art von unbeabsichtigten Nebenwirkungen dieser Ansatz hervorruft.

Tatsächlich ist es nicht einmal eine Lösung, da ich immer noch keinen Tabulator für das letzte Element fälschen kann, das es verwendet.

1
Kev

Ich denke, diese Fehler sind von Autocomplete. Sie können sie möglicherweise deaktivieren, indem Sie vor dem Auslösen des Ereignisses das Attribut "Autocomplete" auf "Off" setzen.

setAttribute('autocomplete','off')
0
Justin Meyer