Toon posts:

[JS] Event.KeyCode vervangen in moderne browsers

Pagina: 1
Acties:

Onderwerpen


  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 12:59
Heren/dames ontwikkelaars,

binnen onze webapplicatie is de wens om de werking van de <enter> toets te vervangen door de functionaliteit van de <tab> toets. Dit zodat de gebruiker met de <enter> toets door de textboxen kan 'skippen'.

"Vroeger" kon dit door middel van een stukje javascript, waarbij je de keyCode van het event overschreef tijdens het onKeyDown event. Dit ging als volgt:
JavaScript:
1
2
3
4
5
function enterToTab() {
    if (event.keyCode == 13) {
        event.keyCode = 9;
    }
}


waarbij je vervolgens deze functie aan een textbox koppelde d.m.v.
C:
1
TextBox1.Attributes["onkeydown"] = "enterToTab()";


Maar wat merk ik nu. Sinds IE9, FF4 en de laatste Google Chrome versies, werkt dit niet meer.

Ik heb wat google zoekwerk gedaan en daarbij kwam ik het volgende tegen:
http://help.dottoro.com/ljqqripa.php
The keyCode property is read-only in Firefox, Opera, Google Chrome and Safari, and it is read/write in Internet Explorer.
Echter in IE9 werkt het ook niet, tenzij ik deze in Compatibility mode draai. Dan werkt 't wel.

Iemand een idee om dit toch werkend te krijgen in de moderne browsers? De applicatie dient in IE (vanaf versie 7), FF (vanaf versie 3) en Chrome te werken.

[Voor 11% gewijzigd door PdeBie op 25-05-2011 14:55. Reden: note verwijderd]


  • Joolee
  • Registratie: Juni 2005
  • Niet online
Wat je nu doet is:
- Event afvangen
- Eventproperties aanpassen
- Event door laten gaan

Waar je aan moet gaan denken is:
- Event afvangen
- Eigen event starten (tab sturen naar de browser of via een eigen javascriptje naar de volgende textbox)
- Originele event stoppen (return false)

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 12:59
Joolee schreef op woensdag 25 mei 2011 @ 13:39:
Waar je aan moet gaan denken is:
- Event afvangen
- Eigen event starten (tab sturen naar de browser of via een eigen javascriptje naar de volgende textbox)
- Originele event stoppen (return false)
Mja, dat had ik ook al bedacht. Maar de vraag 'hoe?' is hier eigenlijk meteen al van toepassing.
Ik kan helaas niet op basis van focus werken, omdat de velden dynamisch opgebouwd worden en daarnaast is mijn kennis van javascript te summier om zelf events te schrijven.

  • RobIII
  • Registratie: December 2001
  • Laatst online: 15:26

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • mocean
  • Registratie: November 2000
  • Laatst online: 21-05 10:47
pdebie schreef op woensdag 25 mei 2011 @ 15:19:
[...]


Mja, dat had ik ook al bedacht. Maar de vraag 'hoe?' is hier eigenlijk meteen al van toepassing.
Ik kan helaas niet op basis van focus werken, omdat de velden dynamisch opgebouwd worden en daarnaast is mijn kennis van javascript te summier om zelf events te schrijven.
Dan zal je het moeten leren, pseudo-code
code:
1
2
3
4
5
6
7
8
9
10
function enterToTab() { 
    if (event.keyCode == 13 || event.keyCode == 9) { 
         // Zoek huidige element op in DOM
         var obj = this.whereAmI();

         // Zoek volgende element in DOM
         var nextObj=obj.findNextFormElement();
         nextObj.focus();         
    } 
}

Koop of verkoop je webshop: ecquisition.com


  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
Volgens mij wil je helemaal niet de enter vervangen in een tab, maar wil je gewoon als er enter gedrukt wordt naar het volgende element.

Ik kan me voorstellen dat op sommige devices (mobiele telefoons?) de tab toets iets anders doet.

Freelance Unity3D developer


  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 30-03 14:15

OkkE

CSS influencer :+

offtopic:
Ik vind het over het algemeen heel onverstandig om standaard functies van de browser te gaan ombouwen. We hebben [TAB] waarom dan [enter] ook?


Het is sowieso goed om tabindex te gebruiken in je formulier. Die kan je in dit geval dan weer mooi gebruiken om de volgende input te selecteren.

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 13-01 10:59
Het gebruik van tabindex is sterk af te raden vanuit accessibility-oogpunt, maar dat terzijde :+

(het is hooguit een lapmiddel om slechte formulieren nog enigszins navigeerbaar te maken)

[Voor 32% gewijzigd door Bosmonster op 25-05-2011 16:04]


  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 12:59
mocean schreef op woensdag 25 mei 2011 @ 15:24:
[...]

Dan zal je het moeten leren, pseudo-code
code:
1
2
3
4
5
6
7
8
9
10
function enterToTab() { 
    if (event.keyCode == 13 || event.keyCode == 9) { 
         // Zoek huidige element op in DOM
         var obj = this.whereAmI();

         // Zoek volgende element in DOM
         var nextObj=obj.findNextFormElement();
         nextObj.focus();         
    } 
}
Ik zal inderdaad hier eens mee gaan spelen.
OkkE schreef op woensdag 25 mei 2011 @ 15:49:
offtopic:
Ik vind het over het algemeen heel onverstandig om standaard functies van de browser te gaan ombouwen. We hebben [TAB] waarom dan [enter] ook?
Eens, maar het is nou eenmaal een requirement die ze gesteld hebben.
De huidige applicatie is namelijk een winapplicatie waarin de gebruikers deze functionaliteit ook hebben. En daarom moet het ook in de nieuwe versie (de huidige webapplicatie die ik aan het bouwen ben) komen.

[Voor 10% gewijzigd door PdeBie op 25-05-2011 16:07]


  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 30-03 14:15

OkkE

CSS influencer :+

Bosmonster schreef op woensdag 25 mei 2011 @ 16:02:
Het gebruik van tabindex is sterk af te raden vanuit accessibility-oogpunt, maar dat terzijde :+

(het is hooguit een lapmiddel om slechte formulieren nog enigszins navigeerbaar te maken)
Hangt er denk ik vanaf hoe je het toepast. Ik geef toe dat tabindex niet nodig is en vaak zelfs weggelaten kan worden. Maar om te zeggen dat ze per definitie slecht zijn, dat zie ik niet direct?
Bosmonster schreef op woensdag 25 mei 2011 @ 16:24:
Dat zal voornamelijk liggen in het feit dat je ze nooit nodig hebt dus :P
Denk 't. :) Maar, het klopt inderdaad dat je een hoop kunt verpesten met verkeerde tabindex.

[Voor 22% gewijzigd door OkkE op 25-05-2011 16:32]

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


  • Davio
  • Registratie: November 2007
  • Laatst online: 29-07-2022
Nou ja, je moet met je tabindex niet heel erg gaan rommelen zodat gebruikers van het bovenste naar het onderste veld springen en weer terug etc...

Je kan misschien beter fieldset gebruiken om controls te groeperen, tenzij dat alweer uit is natuurlijk...

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 13-01 10:59
Dat zal voornamelijk liggen in het feit dat je ze nooit nodig hebt dus :P

En als je ze wel toepast het meestal meer standaardfunctionaliteit (of accessibility-functionaliteit) breekt dan goedmaakt.

@Davio fieldsets zijn praktisch verplicht, zal wel even duren voordat dat uit de gratie is :+ Hoort gewoon bij standaard formulier-opmaak, net als legend, labels, etc.

[Voor 12% gewijzigd door Bosmonster op 25-05-2011 16:25]


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 09-05 14:16

_Thanatos_

Ja, en kaal

Maar wat merk ik nu. Sinds IE9, FF4 en de laatste Google Chrome versies, werkt dit niet meer.
For good reason. Het is standaardgedrag OVERAL in windows en andere OSsen, het is vreselijk slecht om dit te gaan veranderen. De reden dat ze het zo willen is wrs dat de gebruikers bij de klant "gewend" zijn aan een of ander draconisch systeem dat 814 jaar geleden zo gemaakt is. Nieuwe medewerkers hebben dit probleem niet, en daarbij: een nieuw systeem werkt nou eenmaal anders, anders kun je net zo goed een oud systeem behouden.
JavaScript:
1
2
3
function enterToTab() {
  if (event.keyCode == 13 || event.keyCode == 9) {
    //...
Dit is erg slecht, omdat het alléén in IE zal werken. Op andere browsers doet het niets (of zou het niets moeten doen) omdat event een ongedeclareerde variabele is, en daarmee een implied global met undefined als "waarde". In gehoorzame browsers is het event het eerste argument van de event-handler.

MAAR
C:
1
TextBox1.Attributes["onkeydown"] = "enterToTab()";
Dan doe je dat. Omg. Dit lijkt op backend-code en ik hoop voor de rest van de wereld dat dat zo is. Maar dit levert op:
HTML:
1
<input type="text" onkeydown="enterToTab()"/>

Javascript in je HTML*, een global function*, en een verkapte eval()* all-in-frakking-one. En geen manier om aan je event-object te komen in de handler.

De goeie manier is:
JavaScript:
1
2
3
4
5
6
7
document.getElementById("textbox1").keydown = function(e) {
  e = e || window.event;
  //Doe je ding met e.keyCode
  e.keyCode = 32;
  e.returnValue = 32;
  return 32;
};

Je doet er echter goed aan om een framework à la jQuery te gebruiken. Een hoop rariteiten (m.n. in event-spul) worden genormaliseerd en gaan op alle browsers hetzelfde werken:
JavaScript:
1
2
3
4
$("#textbox1").bind("keydown", function(e) {
  //Doe je ding met e.keyCode
  return 32;
});

Niet getest natuurlijk, maar ik verwacht dat het zo makkelijk is.
*) Je hoort te weten waarom deze dingen slecht zijn. Weet je dit niet, dan ga je dat als de wiedeweerga leren :)

日本!🎌


  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 23-07-2021
_Thanatos_ schreef op donderdag 26 mei 2011 @ 00:33:
[...]
For good reason. Het is standaardgedrag OVERAL in windows en andere OSsen, het is vreselijk slecht om dit te gaan veranderen. De reden dat ze het zo willen is wrs dat de gebruikers bij de klant "gewend" zijn aan een of ander draconisch systeem dat 814 jaar geleden zo gemaakt is. Nieuwe medewerkers hebben dit probleem niet, en daarbij: een nieuw systeem werkt nou eenmaal anders, anders kun je net zo goed een oud systeem behouden.
Tja, je zal toch eens een concessie doen vanwege de vraag van de klant, dat is uiteraard ondenkbaar. Wat denkt die klant wel? Jij bepaalt de requirements wel even, het enige wat de klant moet doen is de rekening betalen en zijn klep houden... (Op deze manier ongeveer jouw instelling goed weergegeven?)
Je doet er echter goed aan om een framework à la jQuery te gebruiken. Een hoop rariteiten (m.n. in event-spul) worden genormaliseerd en gaan op alle browsers hetzelfde werken:
Zonder verdere achtergrondinfo is dit gewoon pure waanzin. Waarom zou je een hele jQuery library meesjouwen als je enkel maar 1 dingetje wilt hebben.
*) Je hoort te weten waarom deze dingen slecht zijn. Weet je dit niet, dan ga je dat als de wiedeweerga leren :)
Welkom in de echte wereld waar er geen echt absoluut slechte / goede dingen zijn.

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 09-05 14:16

_Thanatos_

Ja, en kaal

Tja, je zal toch eens een concessie doen vanwege de vraag van de klant, dat is uiteraard ondenkbaar. Wat denkt die klant wel? Jij bepaalt de requirements wel even, het enige wat de klant moet doen is de rekening betalen en zijn klep houden... (Op deze manier ongeveer jouw instelling goed weergegeven?)
Nee, maar de klant heeft niet altijd gelijk. Het is aan jouw (ons) om de klant uit te leggen dat het echt een slecht idee is. De klant heeft gewoon een bepaald probleem en wil daarvoor een oplossing. Het is aan ons om de oplossing te zoeken, niet aan de klant. Een gouden regel die ik geleerd heb, is om 5x na elkaar een waarom-vraag te stellen (met een goed antwoord erop) om tot de bron te komen waarvoor een oplossing moet komen. Soms kom je dan op iets heel anders uit, waar de klant nog blij mee is ook.

Doen wat de klant opdraagt is niet altijd hetzelfde als de klant blij maken. En dingen maken waar je niet achter staat is ook slecht voor je portfolio.
Zonder verdere achtergrondinfo is dit gewoon pure waanzin. Waarom zou je een hele jQuery library meesjouwen als je enkel maar 1 dingetje wilt hebben.
Is het maar 1 "dingetje" dan? Me dunkt dat het een applicatie is waar veel meer (draconische) code in hangt die de verbeteringen van jQuery (of een ander modern framework) kan gebruiken.
Welkom in de echte wereld waar er geen echt absoluut slechte / goede dingen zijn.
Dankje :) De meeste dingen zijn inderdaad niet pure evil of pure goodness, maar helaas bestaat er in javascript wel bijzonder veel bad practice.

[Voor 14% gewijzigd door _Thanatos_ op 26-05-2011 18:03]

日本!🎌


Acties:
  • 0Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 12:59
Ik heb mijn werkgever (die hier als klant dient) geprobeerd over te halen de functionaliteit niet in te bouwen, maar hij houdt voet bij stuk en wilt dat de Enter toets als Tab dient, omdat de eindgebruikers dit nu eenmaal gewend zijn. Ze werken nu ruim 10 jaar met een applicatie waar dit zo in werkt en het pc-kennis niveau van de eindgebruikers is vergelijkbaar met de 'beweeg de muis naar rechterbovenhoek'-reclame. Vandaar de keuze ;)

En over je reactie about mijn code. Waarom geen js-functie toekennen in een attribuut van een html item? Wat is er mis mee? (stuur het me desnoods per prive bericht, zodat we die discussie gescheiden kunnen houden van dit topic).

Verders wil ik aangeven dat ik inmiddels al een oplossing heb gevonden/bedacht. (gedeeltelijk thanks to google).

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function pageLoad() {        
        enterToTab();
}

function enterToTab() {
    $("input").not($(":button")).keypress(function (evt) {
        if (evt.keyCode == 13) {
            iname = $(this).val();
            if (iname !== 'Submit') {
                var fields = $(this).parents('form:eq(0),body').find('button, input, textarea, select');
                var index = fields.index(this);
                if (index > -1 && (index + 1) < fields.length) {
                    fields.eq(index + 1).focus();
                }
                return false;
            }
            return false;
        }
    });
}


Keurig opgelost middels JQuery in plaats van mijn vorige methode. Happy? ;)
Ik wel in ieder geval, want 't werkt als een tierelier.

[Voor 0% gewijzigd door PdeBie op 31-05-2011 08:56. Reden: Typo's]


Acties:
  • 0Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 16-05 22:53
pdebie schreef op maandag 30 mei 2011 @ 15:25:
Keurig opgelost middels JQuery in plaats van mijn vorige methode. Happy? ;)
Ik wel in ieder geval, want 't werkt als een tierelier.
Laat 'keurig' maar achterwege. Zo gebruik je niet de correcte manier om het basis gedrag van een event te stoppen, heb je selectors die nodeloos complex zijn (nl. "form:eq(0)" in een parents selectie, terwijl forms niet genest mogen zijn) en zit er een gehackte oplossing in om met submit buttons om te gaan. Deze werkt niet eens correct, want: wat gebeurt er met een tekstvak waar de gebruiker 'Submit' als tekst opgegeven heeft en dan met de enter toets bevestigt?

Een oplossing ongeveer als het volgende is dan al stukken beter.

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
$( document ).ready( function() {

    // Bind the event to a useful subset of input elements. 
    $( "input, select" )
        .not( ":button, :submit, :image, :file" )
        .bind( "keypress", function ( event ) {
            var fields, index, scope;
            
            if ( event.keyCode !== 13 ) { return; }
            
            // Go up the DOM scope in steps. Start with any enclosing fieldsets.
            // If this yields no successor, try from an enclosing form tag. If this
            // yields no results either, try from the document body directly.           
            scope = $( this ).parent().closest( "fieldset, form, body" );
            while ( scope.length !== 0 ) {
                
                fields = scope.find( ":input" );        
                index = fields.index( this );
            
                // Check if this is not the last input element in the scope.
                // This check is safe, as index will never be < 0. An element
                // is guaranteed to be present as a descendant of one of its
                // ancestors.
                if ( index < fields.length - 1 ) {

                    // Set the new focus, stop the default behaviour of the
                    // key press and exit the event handler.
                    fields.eq( index + 1 ).focus();
                    event.preventDefault();
                    return;
                }
                
                scope = scope.parent().closest( "fieldset, form, body" )
            }
            
            // Fields will still contain the result for the body level's
            // search for valid input elements. If no successor can be
            // found, select the first input element as a 'wrap around'.
            fields.first().focus();
        }
    });
});

Acties:
  • 0Henk 'm!

  • PdeBie
  • Registratie: Juni 2004
  • Laatst online: 12:59
R4gnax schreef op maandag 30 mei 2011 @ 17:21:
[...]

Laat 'keurig' maar achterwege. Zo gebruik je niet de correcte manier om het basis gedrag van een event te stoppen, heb je selectors die nodeloos complex zijn (nl. "form:eq(0)" in een parents selectie, terwijl forms niet genest mogen zijn) en zit er een gehackte oplossing in om met submit buttons om te gaan.
Excusez moi for being a newbie in jquery. ;(

Dat submit verhaal van die textbox heb ik er meteen uitgesloopt, want dat was best een domme bug |:(
Wilde checken of het geen 'submit' control was, maar dat moet dus anders middels .not( ":submit") zoals jij aangaf in je voorbeeld.
Echter ben ik met jouw voorbeeld ook al weer ergens tegenaan gelopen wat ik eerst nog moet oplossen. (heeft te maken met velden die niet op enabled staan). Anyway thanks voor je comments. Ik ga m'n code nog eens herzien :)

(tevens nogmaals aangekaart bij hogerop dat ik de gewenste functionaliteit zinloos vind :P
maar dat terzijde. )

[Voor 5% gewijzigd door PdeBie op 03-06-2011 10:30]


Acties:
  • 0Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 16-05 22:53
pdebie schreef op vrijdag 03 juni 2011 @ 10:29:
Excusez moi for being a newbie in jquery. ;(
Geen probleem. Je moet tenslotte ergens beginnen.
pdebie schreef op vrijdag 03 juni 2011 @ 10:29:
Echter ben ik met jouw voorbeeld ook al weer ergens tegenaan gelopen wat ik eerst nog moet oplossen. (heeft te maken met velden die niet op enabled staan). Anyway thanks voor je comments. Ik ga m'n code nog eens herzien :)
Ah. Ik wist niet dat je ook met uitgeschakelde form elementen aan het werk moest. In dat geval kun je het eens proberen met een extra filter op regel 17 v/h voorgaande script.

JavaScript:
1
fields = scope.find( ":input" ).filter(function(){ return !this.disabled; });
pdebie schreef op vrijdag 03 juni 2011 @ 10:29:
(tevens nogmaals aangekaart bij hogerop dat ik de gewenste functionaliteit zinloos vind :P
maar dat terzijde. )
Ik ken dat gevoel van vechten tegen de bierkaai. Wat ik aan zou raden is om dit stukje script er gewoon op zo'n manier in te steken dat het later ook weer makkelijk weg te halen is en dan gewoon te wachten op de reacties v/d klant. Je kunt het dan altijd makkelijk er weer uit halen. Zorg trouwens wel dat je jouw reeds uitgesproken advies en de reactie daarop nog ergens traceerbaar hebt, dan kan jou later ook niets verweten worden. ;)
Pagina: 1


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee