admin管理员组

文章数量:1394152

How can I detect if the shift key is currently pressed down? I have a text input, and when the user presses the enter key I only want to submit the form if they are not currently pressing the enter key (same form functionality as Facebook Messenger on desktop).

Here is my text input:

<TextInput
    style={styles.input}
    placeholder={'Enter message'}
    onKeyPress={this.handleKeyPress}
/>

And here is the handler:

handleMessageInputKeyPress(e) {
    if(e.nativeEvent.key == "Enter"){
        // Now check if the SHIFT key is currently pressed or not...
    }
}

How can I detect if the shift key is currently pressed down? I have a text input, and when the user presses the enter key I only want to submit the form if they are not currently pressing the enter key (same form functionality as Facebook Messenger on desktop).

Here is my text input:

<TextInput
    style={styles.input}
    placeholder={'Enter message'}
    onKeyPress={this.handleKeyPress}
/>

And here is the handler:

handleMessageInputKeyPress(e) {
    if(e.nativeEvent.key == "Enter"){
        // Now check if the SHIFT key is currently pressed or not...
    }
}
Share Improve this question edited Jan 14, 2017 at 8:42 Leopold Joy asked Jan 14, 2017 at 8:33 Leopold JoyLeopold Joy 4,6604 gold badges29 silver badges38 bronze badges 6
  • 1 e.nativeEvent.shiftKey? – Teemu Commented Jan 14, 2017 at 8:36
  • @Teemu I get undefined when I add console.log(e.nativeEvent.shiftKey); inside the if statement. – Leopold Joy Commented Jan 14, 2017 at 8:41
  • ?? Then simply check 'Shift' instead of 'Enter'? Ah... Shift doesn't fire keypress ... – Teemu Commented Jan 14, 2017 at 8:42
  • @Teemu But I want to check if the Shift key is pressed at the same time as the Enter key. How can I do that? – Leopold Joy Commented Jan 14, 2017 at 8:44
  • 1 You need another event, like keydown or keyup, keypress is not fired by SHIFT, though .shiftKey still should be defined. – Teemu Commented Jan 14, 2017 at 8:45
 |  Show 1 more ment

3 Answers 3

Reset to default 6

You can use event listeners to detect any time a key is pressed (or unpressed), then filter the results for the key you want to use as a conditional. Here's an example using hooks:

  const [shiftHeld, setShiftHeld] = useState(false);


  function downHandler({key}) {
    if (key === 'Shift') {
      setShiftHeld(true);
    }
  }

  function upHandler({key}) {
    if (key === 'Shift') {
      setShiftHeld(false);
    }
  }

  useEffect(() => {
    window.addEventListener('keydown', downHandler);
    window.addEventListener('keyup', upHandler);
    return () => {
      window.removeEventListener('keydown', downHandler);
      window.removeEventListener('keyup', upHandler);
    };
  }, []);

This will change the state to true or false depending on whether the shift key is held down or not. Then you can plug that value in anywhere you need it. Tip: You can use this format to listen for any other key. I had a hard time finding documentation on what the keys are called. If you have trouble finding the key name, implement this code then console log key just before the if statement in the downHandler.

Also, make sure you leave the listeners in a useEffect, otherwise you'll get data leaks.

For those who are still looking for the solution:

It seems the event received by the callback onKeyPress has the following properties:

It's nice to see it also has ctrlKey & altKey.

So the solution would be:

<TextInput
    onKeyPress={event => {
        if (event.shiftKey && event.key === "Enter"){
            // ...
        }
    }} />

create a hook like this

import React, {useEffect, useState} from "react";

const useKeyPress = (keyMap, callbackMap) => {
    const [keyPressed, setKeyPressed] = useState(new Set());

    const downHandler = (event) => {
      event.preventDefault();
      const { key, altKey, shiftKey, ctrlKey } = event;
  
      const modifiers = [];
      if (altKey) modifiers.push('alt');
      if (shiftKey) modifiers.push('shift');
      if (ctrlKey) modifiers.push('ctrl');
  
      // Generate all possible binations of modifiers and key
      const binations = [      [key.toLowerCase()],
        [modifiers.join('+'), key.toLowerCase()],
        [modifiers.reverse().join('+'), key.toLowerCase()]
      ];
  
      for (const bination of binations) {
        const id = keyMap[bination.join('+')];
        const callback = callbackMap[id];
        if (callback) {
          const newKeyPressed = new Set(keyPressed);
          newKeyPressed.add(bination.join('+'));
          setKeyPressed(newKeyPressed);
          callback();
          break;
        }
      }
    };
  
    const upHandler = (event) => {
      event.preventDefault();
      const { key, altKey, shiftKey, ctrlKey } = event;
  
      const modifiers = [];
      if (altKey) modifiers.push('alt');
      if (shiftKey) modifiers.push('shift');
      if (ctrlKey) modifiers.push('ctrl');
  
      // Generate all possible binations of modifiers and key
      const binations = [      [key.toLowerCase()],
        [modifiers.join('+'), key.toLowerCase()],
        [modifiers.reverse().join('+'), key.toLowerCase()]
      ];
  
      for (const bination of binations) {
        const id = keyMap[bination.join('+')];
        const callback = callbackMap[id];
        if (callback) {
          const newKeyPressed = new Set(keyPressed);
          newKeyPressed.delete(bination.join('+'));
          setKeyPressed(newKeyPressed);
          break;
        }
      }
    };
    
      
  
    useEffect(() => {
      window.addEventListener('keydown', downHandler);
      window.addEventListener('keyup', upHandler);
  
      return () => {
        window.removeEventListener('keydown', downHandler);
        window.removeEventListener('keyup', upHandler);
      };
    });
  
    return keyPressed;
  };

export default useKeyPress;
  

Then use can use it like this in your other ponents;

// Keyboard mappings
  const keyMap = {
    'ctrl+shift+p': 'preview',
  };
  const callbackMap = {
    'preview': () => setShowModal(prevModalVisible => !prevModalVisible),
  };
  useKeyPress(keyMap, callbackMap);

With technique you can map any three key binations of your liking

本文标签: javascriptDetect if shift key is down React NativeStack Overflow