PureScript新手求助:无法从键盘事件中获取KeyCode
Hey there! Let's work through this keyboard event issue you're having in PureScript. I remember when I was starting out with functional programming and PureScript, dealing with DOM events felt a bit awkward at first—so let's break this down step by step.
The Core Issue
PureScript's strict type system won't let you directly cast an Event to a KeyboardEvent like you might in vanilla JavaScript. Not all DOM events are keyboard events (think mouse clicks or scroll events), so we need to safely check and convert the event type before accessing keyboard-specific properties like keyCode.
Step-by-Step Solution
First, make sure you're importing the right modules from purescript-web-dom (the standard library for DOM interactions in PureScript):
import Web.DOM.Event (Event, isKeyboardEvent, toKeyboardEvent) import Web.DOM.KeyboardEvent (KeyboardEvent, keyCode, key, code) import Effect (Effect) import Effect.Console (log) import Web.DOM.Document (documentBody) import Web.DOM.Element (addEventListener) import Web.DOM.Event.EventType (EventType(EventType))
Safe Event Conversion & KeyCode Retrieval
Instead of forcing a type cast, use toKeyboardEvent which returns a Maybe KeyboardEvent—this lets you handle both cases where the event is a keyboard event, and where it's not:
-- Your test function, updated to handle type safety test :: Event -> Effect Unit test event = do case toKeyboardEvent event of Just kbEvent -> do -- Get the keyCode (note: this API is deprecated, more on that below) let codeValue = keyCode kbEvent log $ "Key Code: " <> show codeValue -- Recommended alternative: use `key` or `code` for modern browsers let keyValue = key kbEvent log $ "Key Name: " <> keyValue Nothing -> log "Received a non-keyboard event"
Setting Up the Event Listener Correctly
Here's how to wire up your keydown listener to a DOM element (e.g., the document body):
main :: Effect Unit main = do body <- documentBody -- Attach the keydown listener to the body addEventListener body (EventType "keydown") test false
Why This Works
toKeyboardEventchecks if the incomingEventis actually aKeyboardEventunder the hood. If it is, it wraps it in aJust; if not, it returnsNothing.- Using a
caseexpression forces you to handle both scenarios, which aligns with PureScript's functional programming principles of avoiding runtime errors from unsafe casts.
Quick Note on Deprecation
The keyCode property is officially deprecated in modern browsers. It's better to use:
key: Returns the actual character or key name (e.g.,"a","Enter","Shift")code: Returns the physical key position (e.g.,"KeyA","Enter","ShiftLeft")
These are more reliable across different keyboard layouts and browser versions.
内容的提问来源于stack exchange,提问作者Christopher Rozario

