2009-07-03 7 views
26

Ich arbeite mit grundlegenden HTML <input type="text"/> Textfeld mit einem numerischen Wert.Verhindern Standardverhalten in der Texteingabe, während Pfeil nach oben

Ich füge das JavaScript-Ereignis keyup hinzu, um zu sehen, wann der Benutzer die Pfeiltaste nach oben drückt (e.which == 38) - dann inkrementiere ich den numerischen Wert.

Der Code funktioniert gut, aber es gibt eine Sache, die mich nervt. Sowohl Safari/Mac als auch Firefox/Mac bewegen den Cursor ganz am Anfang, wenn ich die Pfeiltaste nach oben drücke. Dies ist ein Standardverhalten für jedes <input type="text"/> Textfeld, soweit ich weiß und es ist sinnvoll.

Dies erzeugt jedoch keinen sehr ästhetischen Effekt des Vor- und Zurückspringens des Cursors (nachdem der Wert geändert wurde).

Der Sprung am Anfang geschieht auf keydown, aber selbst mit diesem Wissen kann ich nicht verhindern, dass es auftritt. Ich habe versucht, die folgenden:

input.addEventListener('keydown', function(e) { 
    e.preventDefault(); 
}, false); 

e.preventDefault() in keyup Veranstaltung Putting auch nicht hilft.

Gibt es eine Möglichkeit, den Cursor daran zu hindern, sich zu bewegen?

Antwort

27

Um die Cursorposition zu erhalten, sichern Sie vor dem Ändern des Werts input.selectionStart.

Das Problem ist, dass WebKit auf keydown reagiert und Opera bevorzugt keypress, also gibt es Kludis: beide werden behandelt und gedrosselt.

var ignoreKey = false; 
var handler = function(e) 
{ 
    if (ignoreKey) 
    { 
     e.preventDefault(); 
     return; 
    } 
    if (e.keyCode == 38 || e.keyCode == 40) 
    { 
     var pos = this.selectionStart; 
     this.value = (e.keyCode == 38?1:-1)+parseInt(this.value,10);   
     this.selectionStart = pos; this.selectionEnd = pos; 

     ignoreKey = true; setTimeout(function(){ignoreKey=false},1); 
     e.preventDefault(); 
    } 
}; 

input.addEventListener('keydown',handler,false); 
input.addEventListener('keypress',handler,false); 
+1

Habe es kaputt gemacht! Vielen Dank, es ist perfekt. :) – riddle

+0

Up vote für "kludge"! Arbeitete für mich, danke für die Antwort. – NotJay

-1

Wahrscheinlich nicht. Sie sollten stattdessen nach einer Lösung suchen, um den Cursor zurück zum Ende des Feldes zu bewegen, wo er war. Der Effekt wäre für den Benutzer der gleiche, da er von einem Menschen zu schnell wahrgenommen wird.

Ich googelte einige und fand dieses Stück Code. Ich kann es jetzt nicht testen und es wird gesagt, um nicht auf IE 6 zu arbeiten.

textBox.setSelectionRange (textBox.value.length, textBox.value.length);

+1

Danke. Wenn Sie input.value aktualisieren, wird der Cursor am Ende zurück bewegt. So kann ich die Position des Cursors erkennen und sie dann wiederherstellen, nachdem die Änderung vorgenommen wurde (z. B. in der Mitte der Zahl). Aber ich bin immer noch auf der Suche nach einer besseren Lösung, wenn es verfügbar ist. – riddle

0

Ich testete den Code und es scheint, dass es das Ereignis abbricht, aber wenn Sie nicht den Pfeil für sehr kurze Zeit drücken - es feuert Tastendruckereignis und dieses Ereignis bewegt tatsächlich den Cursor. Verwenden Sie preventDefault() auch im keypress Event-Handler und es sollte in Ordnung sein.

+0

Unglücklicherweise verhindert 'e.preventDefault()' im 'keypress'-Ereignis, dass ich dort etwas eingeben kann (ich möchte, dass Eingaben wie in Firebug funktionieren).Und es löst mein Problem zumindest in meinem Browser nicht - der Cursor springt immer noch ganz am Anfang. – riddle

13

fand ich, dass eine bessere Lösung nur auf return false; ist den Standardpfeil Verhalten zu verhindern:

input.addEventListener("keydown", function(e) { 
    if (e.keyCode === 38 || e.keyCode === 40) return false; 
}, false); 
+0

Danke Mann. Die Idee besteht darin, das Keydown-Ereignis anstelle von keyup zu verwenden. –

+4

Rechts - Keydown ist der Trick. Beachten Sie, dass die Rückgabe von false scheinbar die gesamte Verbreitung des Ereignisses stoppt, während 'preventDefault()' das Ereignis durch das Eingabefeld ignorieren lässt, während es anderen Listenern erlaubt, es zu handhaben, wenn es aufplatzt. – CmdrMoozy

+2

@Lukas, Ihre Lösung hat am besten für mich funktioniert. Ich rufe jedoch 'e.preventDefault();' anstatt 'false' zurück. Letzteres erreichte nicht das Einfrieren des Aufwärts-Tasten-Verhaltens. Danke, dass Sie eine alternative, einfachere Lösung veröffentlicht haben. –

4

Eigentlich ist es eine bessere und einfachere Methode, um diese Arbeit zu tun.

$('input').bind('keydown', function(e){ 
    if(e.keyCode == '38' || e.keyCode == '40'){ 
     e.preventDefault(); 
    } 
}); 

Ja, es ist so einfach!

+0

Sie sind ein Held. danke – zeeks

+0

danke, es hat den Job gemacht –

+0

Sie rettete mich nur aus stundenlang mit diesem Problem zu tun, danke! –