frame 监听按键事件

  1. 使用hotkeys-js监听按键事件

当按下相关按键时,控制台会输出对应信息

import { useEffect } from 'react';
import hotkeys from 'hotkeys-js';

const App = () => {
  useEffect(() => {
    // 按下删除键
    hotkeys('backspace', () => {
      console.log('backspace');
    });

    // 同时按下command+z
    hotkeys('command+z', () => {
      console.log('command+z');
    });

    // 同时按下shift+command+z
    hotkeys('shift+command+z', () => {
      console.log('shift+command+z');
    });
  }, []);
  return <></>;
};

export default App;
  1. 当页面中嵌套Frame,且鼠标定位在Frame中时,hotkeys-js无法正常监听到按键事件,这是由于按键事件被Frame内部处理了
import { useEffect } from 'react';
import hotkeys from 'hotkeys-js';
import Frame from 'react-frame-component';

const Image = () => {
  useEffect(() => {
    hotkeys('backspace', () => {
      console.log('backspace');
    });

    hotkeys('command+z', () => {
      console.log('command+z');
    });

    hotkeys('shift+command+z', () => {
      console.log('shift+command+z');
    });
  }, []);
  return (
    <Frame width={375} height={667} style={{ border: '1px solid red' }}>
      <>frame</>
    </Frame>
  );
};

export default Image;
  1. 解决方式,让frame监听按键事件,并把事件抛给外部
import { useEffect, useState } from 'react';
import hotkeys from 'hotkeys-js';
import Frame from 'react-frame-component';

const App = () => {
  const [element, setElement] = useState<HTMLIFrameElement | null>(null);

  useEffect(() => {
    hotkeys('backspace', () => {
      console.log('backspace');
    });

    hotkeys('command+z', () => {
      console.log('command+z');
    });

    hotkeys('shift+command+z', () => {
      console.log('shift+command+z');
    });
  }, []);

  useEffect(() => {
    if (!element) {
      return;
    }

    const handler = (e: KeyboardEvent) => {
      window.document.documentElement.dispatchEvent(e);
    };

    if (element && element.contentDocument) {
      setTimeout(() => {
        element.contentDocument!.addEventListener('keydown', handler);
      }, 200);
    }
  }, [element]);

  return (
    <Frame
      width={375}
      height={667}
      style={{ border: '1px solid red' }}
      ref={el => setElement(el)}>
      <>frame</>
    </Frame>
  );
};

export default App;
  1. 出现报错
    请添加图片描述
    可以通过克隆改事件解决
const eClone = new KeyboardEvent(e.type, e);
window.document.documentElement.dispatchEvent(eClone);
  1. 完整代码
import { useEffect, useState } from 'react';
import hotkeys from 'hotkeys-js';
import Frame from 'react-frame-component';

const App = () => {
  const [element, setElement] = useState<HTMLIFrameElement | null>(null);

  useEffect(() => {
    hotkeys('backspace', () => {
      console.log('backspace');
    });

    hotkeys('command+z', () => {
      console.log('command+z');
    });

    hotkeys('shift+command+z', () => {
      console.log('shift+command+z');
    });
  }, []);

  useEffect(() => {
    if (!element) {
      return;
    }

    const handler = (e: KeyboardEvent) => {
      e.preventDefault(); //阻止本身事件
      const eClone = new KeyboardEvent(e.type, e);
      window.document.documentElement.dispatchEvent(eClone);
    };

    if (element && element.contentDocument) {
      setTimeout(() => {
        element.contentDocument!.addEventListener('keydown', handler);
      }, 200);
    }
  }, [element]);

  return (
    <Frame width={375} height={667} style={{ border: '1px solid red' }} ref={el => setElement(el)}>
      <>frame</>
    </Frame>
  );
};

export default App;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值