Sie sind auf Seite 1von 5

Rick Strahl's Web Log

Wind, waves, code and everything in between...


ASP.NET C#ContactArticlesProductsSearch
HTML5 JavaScript AngularJs

A Key Code Checker for DOM Keyboard Events


December08,2011fromMaui,Hawaii

Tweet

15

Ifyou'veeverwrittensomecodethatneedstodealwithindividualkeystrokesenteredandto'translate'orparsethem,you've
probablyfiguredoutthatwhileonthesurfaceitalllooksprettyeasywithDOMeventprocessing,it'sactuallyquitetrickytoget
accuratekeyinformation.ThereareseveralkeyboardeventpropertiesavailableandevenwithjQueryvariousbrowsers
handletheseeventpropertiesslightlydifferently.
Infact,IrealizedthatalmosteverytimeIrunintoaproblemwithkeyCodesineventhandlingcodeIaddabunchofconsole.log
statementstofigureoutexactlywhatkeyCodesarecomingbackforeachoftheavailableevents.SotonightIsatdownand
threwtogetherasmallformthatletsmeseeallthisinformationataglanceononepage.
YoucancheckoutmyKeyCodeTesterandplayaroundwithitinvariousbrowsers:

TrytheKeyCodeCheckerExample
Ifyoutrythisinvariousbrowsers,you'llfindthatyougetaratherlargedivergenceofvaluesforthevariousevents.
Butbeforewelookattheactualresultsandsomesuggestions,let'sbackupforasecondandexplainhowkeyhandlinginthe
DOMworks.

Key Event Handling for the DOM


TheHTMLDOMhassupportforkeyboardeventsthatfirewhenyoupresskeysanywhereinthedocument.Themostcommon
placewheretheeventtrappingmattersisoninputcontrolslikeatextbox,butitalsocanworkinanyotherDOMelementlikea
<div>.
TheDOMkeyboardinputeventmodelhasanumberofeventstohandlekeyeventsthatyoucanhandle:
keydown
keypress
keyup

Theseeventsarefairlyselfexplanatoryonthesurfaceandtheyfireintheordershownabove.Eacheventcanbehookedupto
aneventhandlerthatreceivesaDOMeventparameterwhichcontainsinformationlikekeyCode,charCodeandwhichaswellas
shift,ctl,altstatesyoucanlookat.MostmodernbrowserssupportthekeyCode,charCodeandwhichproperties.whichisa
specialpropertythatreturnsthe'significant'valuefromaneventwhichinthecaseofthekeyeventstendstobethekeyCodeor
ifthatisemptythecharCode.charCodeandwhicharenotavailableonoldversionsofIEpreversion9.Thiscangettrickyto
checkforquickly.andthisiswherejQuerycomesinandprovidesatleastaminimalbitofnormalizationoftheseeventvalues.

jQuery Event Normalization of Key Event Properties


jQuery'sEventObjectsupportskeyCode,charCodeandwhichpropertiesaswell,butyoutypicallyshouldusethewhichproperty
withit.jQuerynormalizeswhichbasedonkeyCodeorcharCode.ItcheckskeyCodefirstandifthat'semptyreadsthecharCode
whichshouldyieldavalidkeyboardcode.
Backtothekeyboardevents:keydownfiresasakeyispresseddown.keypressisfiredimmediatelyafterkeydown,butunlike
keydownandkeyupitfiresonlyon'visible'charactersthatareprintable(FireFoxandOperadon'tfollowthespecandalways
fire).keyupfiresafterkeypresswhenthekeysarereleased.
Atanypointduringtheeventhandlerprocessingforthekeyboardeventsyoucanreturnfalsewhichcausestheeventbubbling
tostop.Whenfalseisreturnedfurtherprocessingstopsandkeyeventsfollowingthecurrentkeyeventwon'tfire.Ifyoureturn
falsefromkeyDown,keypressandkeyupwillnotbefired.
UsingjQueryit'sveryeasytohandlekeyboardevents.Here'sanexampleforkeydownhandling:
$("#txtKey")
.keydown(function(e){
varkeyCode=e.keyCode;
varwhich=e.which;
varcharCode=e.charCode;

//..dosomethingforkeyhandling
//passthroughkeystrokewithtrue
//keepkeystrokefromprocessingfurther(orgetentered)withfalse
returntrue;
});

Sample Implementation
Theaboveformwasimplementedusingalittlebitofscriptcodethatbasicallyhandlesallthreekeyevents.Itthencallsa
commonfunctionanddisplaysthevariouskeycodevaluesintheappropriateboxinthepage.
Thecodetodothisisprettysimple,butIpostithereasitgivesalittlebitofinsightonhowthevariouskeyeventproperties
work:
<scripttype="text/javascript">
$(function(){
$("#txtKey")
.focus()
.keypress(handleKey)
.keydown(handleKey)
.keyup(handleKey);
});
functionhandleKey(e){
varkeyCode=e.keyCode;
varcharCode=e.charCode;
varwhich=e.which;
vartype=e.handleObj.origType;
varorig=e.orignalEvent;
if(!keyCode)
keyCode="0";
if(!which)
which="0";
if(type=="keydown"){
$("#divDown.mainvalue").text(keyCode);
$("#divCharCodeDown.mainvalue").text(charCode);
$("#divWhichDown.mainvalue").text(which);
$("#divCharTyped.mainvalue:eq(1)")
.text("")
.text(String.fromCharCode(keyCode));
//alsoclearoutkeypressvaluesincaseitdoesn'tfire
$("#divCharTyped.mainvalue:eq(0)")
.html("&nbsp;")

$("#divPress.mainvalue").text("");
$("#divCharCodePress.mainvalue").text("");
$("#divWhichPress.mainvalue").text("");
}
elseif(type=="keypress"){
$("#divPress.mainvalue").text(keyCode);
$("#divCharCodePress.mainvalue").text(charCode);
$("#divWhichPress.mainvalue").text(which);

$("#divCharTyped.mainvalue:eq(0)")
.text(String.fromCharCode(which));
}
elseif(type=="keyup"){
$("#divUp.mainvalue").text(keyCode);
$("#divCharCodeUp.mainvalue").text(charCode);
$("#divWhichUp.mainvalue").text(which);
$("#divCharTyped.mainvalue:eq(2)")
.text("")
.text(String.fromCharCode(keyCode));
}

//mustreturntrueinorderforkeypresstofire
//inallbrowsers.RemovecharacterusingsetTimeout
//todelayandcleartextafterthefact.
setTimeout(function(){$("#txtKey").val("");},2);
//alwaysreturntruesokeypressfires
returntrue;
}
</script>

Browser Divergence
Imentionedearlierthatvariousbrowsershandlethevariouskeycodesdifferently.Checkoutthefollowingwhenpressingthe'a'
keyinFireFox,Chrome,IE(8standardsmode),Operarespectively:

Youcanseethedivergencehere.FireFoxdoesn'tgetagoodkeyCodeinthekeyPressevent,andinsteadgivesacharCode.All
otherbrowserstestedreturnavalidkeycodeinallevents.NoticethatallbrowsersreturnconsistentresultswithjQueryusing
thee.whichproperty.ThewhichpropertyisclearlywhatyoushouldusetogetareliableandconsistentkeyCodevaluethat
worksacrossallbrowsers.

Suggestions
Usee.whichwhencheckingforKeyCodes
WhenusingjQueryit'sbesttousee.whichinkeyeventstocheckforkeycodes.e.whichnormalizesbetweenallkey
combinationsthatIsawandprovidesthemostconsistentvalueacrossbrowsers.
IfyouneedaCharacterValuefromaKeyCodeusekeypressEvent
Whenyouneedtogetacharactervaluefromakeyeventhandlethekeypresseventasit'stheonlyonethatcan
receiveatranslatedkeycodethatreflectstheactualcharacterthattheusertypedandthatwouldappearinthetext

box.YoucanuseString.fromCharCode(e.which)togettheprintablecharacter.
WatchoutforkeypressEventDifferences
Keepinmindthatthekeypressonlyfiresonprintablecharactersandthatthekeycodevaluefore.whichwillbe
differentthanthoseinkeydownandkeyup.Ifyouneedtohandlebothprintableandspecialkeysyoumighthaveto
implementbothkeyDownandkeyPress.

Hopefullythisutilityplussomeofthesesuggestionswillproveusefultosomeofyou.IknowitwillbetomethenexttimeIhave
aneedtomanipulatekeystrokesinmyJavaScriptcodeinformationlikethishasahalflifeofabout2dayswithmeafteritfiles
outofmybrainagain:).Thisblogpostshouldhelpmeremembernexttime

Other Posts you might also like


AngularJsandPromiseswiththe$httpService
JavaScriptJSONDateParsingandrealDates
HTML5Inputtype=dateFormattingIssues
RestrictingInputinHTMLTextboxestoNumericValues

PostedinJavaScriptjQueryHTML
Tweet

15

Feedback for this Post

AddaComment

RickStrahl,WestWindTechnologies,20052015