Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

document.onkeydown temporaer deaktivieren?

1 view
Skip to first unread message

Ulli Horlacher

unread,
Jul 14, 2022, 6:41:58 PM7/14/22
to
Ich hab mich grad in den Fuss geschossen :-}

Auf einer HTML-Seite hab ich folgenden Javascript-Code zum
vorwaerts/rueckwaerts-Blaettern (fuer Bildergallerie):

<script>
document.onkeydown = function(e) {
switch (e.keyCode) {
case 8: document.getElementById("previous").click(); break;
case 32: document.getElementById("next").click(); break;
case 37: document.getElementById("previous").click(); break;
case 39: document.getElementById("next").click(); break;
}
};
</script>

Damit kann ich mit SPACE oder Cursor-rechts weiterblaettern und mit
BACKSPACE oder Cursor-links zurueck. Funktionierte bisher prima.

Nun hab ich die HTML-Seite um ein <textarea> erweitert.
Wenn ich da drin SPACE BACKSPACE oder Cursor eintippe, um den Text zu
editieren wird die entsprechende Javascriptfunktion aufgerufen und
vor/zurueck geblaettert. Nicht das, was ich haben will :-}

(Wie) kann ich das document.onkeydown innerhalb des <textarea>
deaktivieren oder gibts noch eine ganz andere Moeglichkeit?



--
Ullrich Horlacher Server und Virtualisierung
Rechenzentrum TIK
Universitaet Stuttgart E-Mail: horl...@tik.uni-stuttgart.de
Allmandring 30a Tel: ++49-711-68565868
70569 Stuttgart (Germany) WWW: http://www.tik.uni-stuttgart.de/

Peter J. Holzer

unread,
Jul 14, 2022, 7:28:56 PM7/14/22
to
On 2022-07-14 22:41, Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:
> Auf einer HTML-Seite hab ich folgenden Javascript-Code zum
> vorwaerts/rueckwaerts-Blaettern (fuer Bildergallerie):
>
> <script>
> document.onkeydown = function(e) {
> switch (e.keyCode) {
> case 8: document.getElementById("previous").click(); break;
> case 32: document.getElementById("next").click(); break;
> case 37: document.getElementById("previous").click(); break;
> case 39: document.getElementById("next").click(); break;
> }
> };
> </script>
>
> Damit kann ich mit SPACE oder Cursor-rechts weiterblaettern und mit
> BACKSPACE oder Cursor-links zurueck. Funktionierte bisher prima.
>
> Nun hab ich die HTML-Seite um ein <textarea> erweitert.
> Wenn ich da drin SPACE BACKSPACE oder Cursor eintippe, um den Text zu
> editieren wird die entsprechende Javascriptfunktion aufgerufen und
> vor/zurueck geblaettert. Nicht das, was ich haben will :-}
>
> (Wie) kann ich das document.onkeydown innerhalb des <textarea>
> deaktivieren oder gibts noch eine ganz andere Moeglichkeit?

Events werden durch den DOM-Tree nach oben weitergereicht, bis sie
schließlich bei der Wurzel (document) ankommen. Um das zu verhindern,
musst Du das Event an der Stelle, wo du das stoppen willst, abfangen und
stopPropagation() aufrufen.

Hier also z.B. in jeder textarea:

for (el of document.getElementsByTagName("textarea")) {
el.onkeydown = function(e) {
e.stopPropagation();
};
}

Und wahrscheinlich auch bei den Inputs, wenn du welche hast. Vielleicht
besser eine "nopropagate" Class einzuführen als Elementnamen zu
verwenden?

Ulli Horlacher

unread,
Jul 15, 2022, 3:10:53 AM7/15/22
to
Peter J. Holzer <hjp-u...@hjp.at> wrote:
> On 2022-07-14 22:41, Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:
> > Auf einer HTML-Seite hab ich folgenden Javascript-Code zum
> > vorwaerts/rueckwaerts-Blaettern (fuer Bildergallerie):
> >
> > <script>
> > document.onkeydown = function(e) {
> > switch (e.keyCode) {
> > case 8: document.getElementById("previous").click(); break;
> > case 32: document.getElementById("next").click(); break;
> > case 37: document.getElementById("previous").click(); break;
> > case 39: document.getElementById("next").click(); break;
> > }
> > };
> > </script>
> >
>
> Events werden durch den DOM-Tree nach oben weitergereicht, bis sie
> schließlich bei der Wurzel (document) ankommen. Um das zu verhindern,
> musst Du das Event an der Stelle, wo du das stoppen willst, abfangen und
> stopPropagation() aufrufen.
>
> Hier also z.B. in jeder textarea:
>
> for (el of document.getElementsByTagName("textarea")) {
> el.onkeydown = function(e) {
> e.stopPropagation();
> };
> }

Wo genau bau ich das ein?
Bisher hab ich:

<textarea name="description" cols="80" rows="2">$description</textarea>

> Und wahrscheinlich auch bei den Inputs, wenn du welche hast. Vielleicht
> besser eine "nopropagate" Class einzuführen als Elementnamen zu
> verwenden?

Mir faellt noch was anderes ein:
In meinem Javascript-Code oben, kann ich da nicht eine Abfrage einbauen,
ob der Fokus im <textarea> ist und dann nichts machen?

Arno Welzel

unread,
Jul 15, 2022, 4:27:51 AM7/15/22
to
Ulli Horlacher:

> Ich hab mich grad in den Fuss geschossen :-}
>
> Auf einer HTML-Seite hab ich folgenden Javascript-Code zum
> vorwaerts/rueckwaerts-Blaettern (fuer Bildergallerie):
>
> <script>
> document.onkeydown = function(e) {
> switch (e.keyCode) {
> case 8: document.getElementById("previous").click(); break;
> case 32: document.getElementById("next").click(); break;
> case 37: document.getElementById("previous").click(); break;
> case 39: document.getElementById("next").click(); break;
> }
> };
> </script>

Wenn Du schon switch() benutzt, warum dann nicht so, wie es eigentlich
vorgesehen ist?

<script>
document.onkeydown = function(e) {
switch (e.keyCode) {
case 8:
case 37:
document.getElementById("previous").click();
break;
case 32:
case 39:
document.getElementById("next").click();
break;
}
};
</script>

> Damit kann ich mit SPACE oder Cursor-rechts weiterblaettern und mit
> BACKSPACE oder Cursor-links zurueck. Funktionierte bisher prima.
>
> Nun hab ich die HTML-Seite um ein <textarea> erweitert.
> Wenn ich da drin SPACE BACKSPACE oder Cursor eintippe, um den Text zu
> editieren wird die entsprechende Javascriptfunktion aufgerufen und
> vor/zurueck geblaettert. Nicht das, was ich haben will :-}>
> (Wie) kann ich das document.onkeydown innerhalb des <textarea>
> deaktivieren oder gibts noch eine ganz andere Moeglichkeit?

In dem Du bei deiner Funktion nicht nur prüfst, *was* passiert ist,
sondern auch *wo*.

Siehe auch
<https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget>.

Auf die Schnelle und ungeprüft:

<!-- Tastureingaben hier werden ignoriert -->
<textarea id="mytext"></textarea>

<script>
document.onkeydown = function(e) {
if(e.currentTarget.id != 'mytext') {
switch (e.keyCode) {
case 8:
case 37:
document.getElementById("previous").click();
break;
case 32:
case 39:
document.getElementById("next").click();
break;
}
}
};
</script>


--
Arno Welzel
https://arnowelzel.de

Arno Welzel

unread,
Jul 15, 2022, 4:30:13 AM7/15/22
to
Arno Welzel:
Ergänzend:

Mit console.log() kannst Du Dir auch Meldungen in die Browser-Konsole
(zu öffnen mit F12) ausgeben lassen und so mehr über die Objekte
erfahren, die da so erzeugt werden. Bei aktuellen Browsern kann man die
Objekte in der Konsole auch öffnen und deren Eigenschaften untersuchen:

<script>
document.onkeydown = function(e) {

console.log('Tastatureingabe, Event:');
console.log(e);

Ulli Horlacher

unread,
Jul 15, 2022, 4:55:05 AM7/15/22
to
Arno Welzel <use...@arnowelzel.de> wrote:

> > <script>
> > document.onkeydown = function(e) {
> > switch (e.keyCode) {
> > case 8: document.getElementById("previous").click(); break;
> > case 32: document.getElementById("next").click(); break;
> > case 37: document.getElementById("previous").click(); break;
> > case 39: document.getElementById("next").click(); break;
> > }
> > };
> > </script>
>
> Wenn Du schon switch() benutzt, warum dann nicht so, wie es eigentlich
> vorgesehen ist?

Weil ich ein Javascript-Stuemper bin :-}


> document.onkeydown = function(e) {
> switch (e.keyCode) {
> case 8:
> case 37:
> document.getElementById("previous").click();
> break;
> case 32:
> case 39:
> document.getElementById("next").click();
> break;
> }
> };

Ja, das sieht besser aus, nehm ich! :-)


> In dem Du bei deiner Funktion nicht nur prüfst, *was* passiert ist,
> sondern auch *wo*.
>
> Siehe auch
> <https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget>.
>
> Auf die Schnelle und ungeprüft:
>
> <!-- Tastureingaben hier werden ignoriert -->
> <textarea id="mytext"></textarea>
>
> <script>
> document.onkeydown = function(e) {
> if(e.currentTarget.id != 'mytext') {
> switch (e.keyCode) {
> case 8:
> case 37:
> document.getElementById("previous").click();
> break;
> case 32:
> case 39:
> document.getElementById("next").click();
> break;
> }
> }
> };
> </script>

Auf die Idee bin ich dann auch gekommen, wusste bloss nicht wie konkret
zu implementieren (currentTarget.id kannte ich nicht).
Also war meine Idee prinzipiell richtig :-)

Prima, mach ich so, danke!

Arno Welzel

unread,
Jul 15, 2022, 6:04:33 AM7/15/22
to
Ulli Horlacher:
Über currentTarget kannst Du auch ermitteln, welche Art von Element das
ist und generell <textarea> oder <input type="text"> ausschliessen, etwa
so - auch unter Berücksichtigung der Prinzipien "return early" statt
Abfragen, die ganze Code-Blöcke überspringen und "yoda expression", um
versehentliche Zuweisungen zu vermeiden, weil man "=" statt "=="
geschrieben hat.

Hinweis: die Element-Namen sind immer in Großbuchstaben, egal wie es in
HTML geschrieben wurde.

Auch ungetestet - aber das Prinzip sollte klar sein:

<script>
document.onkeydown = function(e) {
if('TEXTAREA' == e.currentTarget.nodename) {
return;
}

if('INPUT' == e.currentTarget.nodeName) {
if('text' == e.getAttribute('type')) {
return;
}
}

switch (e.keyCode) {
case 8:
case 37:
document.getElementById("previous").click();
break;
case 32:
case 39:
document.getElementById("next").click();
break;
}
};
</script>

Siehe dazu auch:

<https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName>
<https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute>

Peter J. Holzer

unread,
Jul 15, 2022, 6:36:48 AM7/15/22
to
On 2022-07-15 07:10, Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:
> Peter J. Holzer <hjp-u...@hjp.at> wrote:
>> On 2022-07-14 22:41, Ulli Horlacher <fram...@rus.uni-stuttgart.de> wrote:
>> > Auf einer HTML-Seite hab ich folgenden Javascript-Code zum
>> > vorwaerts/rueckwaerts-Blaettern (fuer Bildergallerie):
>> >
>> > <script>
>> > document.onkeydown = function(e) {
[...]
>> > };
>> > </script>
>> >
[...]
>> Hier also z.B. in jeder textarea:
>>
>> for (el of document.getElementsByTagName("textarea")) {
>> el.onkeydown = function(e) {
>> e.stopPropagation();
>> };
>> }
>
> Wo genau bau ich das ein?

Die Textareas müssen bereits existieren, wenn das läuft, also am Ende
vom Body oder in einem <script defer> Block.

(Ich habe zum Testen Deinen Block ans Ende vom Body gestellt und das
dann einfach in den gleichen script-Block geschrieben)

>> Und wahrscheinlich auch bei den Inputs, wenn du welche hast. Vielleicht
>> besser eine "nopropagate" Class einzuführen als Elementnamen zu
>> verwenden?
>
> Mir faellt noch was anderes ein:
> In meinem Javascript-Code oben, kann ich da nicht eine Abfrage einbauen,
> ob der Fokus im <textarea> ist und dann nichts machen?

Ja, kannst Du auch. Ich finde es übersichtlicher, wenn jeder
Event-Handler sowenig wie möglich macht und die Auswirkungen lokal
begrenzt sind, aber das ist Geschmackssache.

hp
0 new messages