js上下左右快捷键与浏览器滚动条默认键产生冲突

1,015 阅读2分钟

之前在工作中有一个需求: 一个很简单的上下左右快捷键切换菜单列表,如下图所示, 用户按下上下键切换蓝色案列,左边蓝色菜单案例就上下切换选中,可是当main盒子内容过多出现滚动条时,就会触发滚动条的默认行为,跟着上下滑动,当时想着很简单就直接e.preventDefault()阻止默认行为就可以了,

image.png

这是我的设置快捷键该功能的代码:

useEffect(() => {
    const onkeydown = (e) => {
      e.preventDefault(); // 阻止上下左右键触发滚动条的默认行为
      
      // 我的按键事件功能代码,可以不用看
      const rightDom = document.querySelector('.subcenter .rightClick');
      const leftDom = document.querySelector('.subcenter .leftClick');
      if (e.keyCode === 38) {
        leftDom.click();
      } else if (e.keyCode === 40) {
        rightDom.click();
      }
    };
    window.addEventListener('keydown', onkeydown);
    return () => {
      window.removeEventListener('keydown', onkeydown);
    };
  }, []);

当时测试一下,按上下键,滚动条果然没跟着上下滑动,不错,轻松搞定! 可是过了一个月后,突然发现左上角条件查询框无法输入数字了,最后发现是我上面代码中的e.preventDefault()导致的,难道数字键也是浏览器默认按键?于是我就将上面的代码改进了一下,通过keyCode值判断,只有在按下上下左右键时,才进行阻止默认行为

 useEffect(() => {
    const onkeydown = (e) => {
    // 阻止上下左右键触发浏览器滚动条的默认行为,
      const keyCodes = [40, 39, 38, 37];
      if (keyCodes.includes(e.keyCode)) { // 这里用了es6数组includes方法,等同于if(e.kecode===40||e.kecode===39||e.kecode===38||e.kecode===37||)
        e.preventDefault(); 
      }
      
      // 我的按键事件功能代码,可以不用看
      const rightDom = document.querySelector('.subcenter .rightClick');
      const leftDom = document.querySelector('.subcenter .leftClick');
      if (e.keyCode === 38) {
        leftDom.click();
      } else if (e.keyCode === 40) {
        rightDom.click();
      }
    };
    window.addEventListener('keydown', onkeydown);
    return () => {
      window.removeEventListener('keydown', onkeydown);
    };
  }, []);

总结:

使用window全局监听键盘事件时,为了阻止默认行为最好不要直接就e.preventDefault,你不知道这样会阻止你其他按键功能的使用,存在隐藏的风险,所以最好用keycode值判断一下,再使用e.preventDefault