最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Tell if shift is being held in onClick in React - Stack Overflow

programmeradmin1浏览0评论

I need to fire an onClick only if meta(mac) / ctrl(win) is being held when it's clicked.

Here's what I tried:

const [shiftOn, setShiftOn] = useState(false)

  useEffect(() => {
    document.addEventListener('keydown', (e) => {
      e.preventDefault()
      if ((e.metaKey || e.ctrlKey) && e.code === 'KeyC') {
        setShiftOn(true)
      }
    })
  })

  useEffect(() => {
    document.addEventListener('keyup', (e) => {
      e.preventDefault()
      if ((e.metaKey || e.ctrlKey) && e.code === 'KeyC') {
        setShiftOn(false)
      }
    })
  })

  const highlightCol = () => {
    console.log(shiftOn) // always false
    if (shiftOn) ... do something
  }

const col = (
        <td onClick={highlightCol} {...tdProps}>
          {colName}
        </td>

I need to fire an onClick only if meta(mac) / ctrl(win) is being held when it's clicked.

Here's what I tried:

const [shiftOn, setShiftOn] = useState(false)

  useEffect(() => {
    document.addEventListener('keydown', (e) => {
      e.preventDefault()
      if ((e.metaKey || e.ctrlKey) && e.code === 'KeyC') {
        setShiftOn(true)
      }
    })
  })

  useEffect(() => {
    document.addEventListener('keyup', (e) => {
      e.preventDefault()
      if ((e.metaKey || e.ctrlKey) && e.code === 'KeyC') {
        setShiftOn(false)
      }
    })
  })

  const highlightCol = () => {
    console.log(shiftOn) // always false
    if (shiftOn) ... do something
  }

const col = (
        <td onClick={highlightCol} {...tdProps}>
          {colName}
        </td>

Share Improve this question asked Sep 24, 2020 at 18:30 BobbyOrr4BobbyOrr4 4021 gold badge6 silver badges16 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 7

You're almost there -- metaKey, shiftKey, etc are what you're looking for -- but you're looking for them in the wrong place: those will simply be boolean properties on the click event itself. You do not need to check for separate keydown or keyup events on the shift or cmd keys, so can delete everything you have in a useEffect.

All you need is the single click handler:

  const highlightCol = e => {
    if (e.shiftKey) {
      // shift key was down during the click
    }
    if (e.ctrlKey) {
      // ctrl key was down during the click 
    }
  }

The onClick will always be fired; just check its event's shiftKey (or metaKey or altKey or ctrlKey) properties to decide whether to do anything in it.

Different browser can have different implementations of detecting pressed keys.
I think the problem here is that you detect ctrl/meta key incorrectly.

Try to look into this service to find out what ways you have to detect particular key.

Below is what it shows for me when I press ctrl key on win.

It is better to use several methods of detecting keys to cover all browsers and platforms.

You may wrong in the way detect control key. By the way, just register event listener 1 time.

const Component =(props)=>{
    const [valueFromChild, setValueFromChild] = useState('');

    const [shiftOn, setShiftOn] = useState(false)

    useEffect(() => {
        document.addEventListener('keydown', (e) => {
            console.log('dow', e);
            e.preventDefault()
            if (e.key === 'Control') {
                setShiftOn(true)
            }
        })
    }, [])

    useEffect(() => {
        document.addEventListener('keyup', (e) => {
            console.log('up', e);
            e.preventDefault()
            if (e.key === 'Control') {
                setShiftOn(false)
            }
        })
    }, [])

    const highlightCol = () => {
        console.log(shiftOn) // always false
        if (shiftOn) {

        }
    }

    return <>
        {shiftOn ? 'on' : 'off'}
        <button onClick={highlightCol} > Click </button>
        </>
}
发布评论

评论列表(0)

  1. 暂无评论