首页 > 技术文章 > 移动的小人 键码配合事件侦听

zqm0924 2020-04-12 22:33 原文

鼠标事件的种类

鼠标事件指与鼠标相关的事件,继承了MouseEvent接口。具体的事件主要有以下一些。

  • click:按下鼠标(通常是按下主按钮)时触发。

  • dblclick:在同一个元素上双击鼠标时触发。

  • mousedown:按下鼠标键时触发。

  • mouseup:释放按下的鼠标键时触发。

  • mousemove:当鼠标在一个节点内部移动时触发。当鼠标持续移动时,该事件会连续触发。为了避免性能问题,建议对该事件的监听函数做一些限定,比如限定一段时间内只能运行一次。

  • mouseenter:鼠标进入一个节点时触发,进入子节点不会触发这个事件(详见后文)。

  • mouseover:鼠标进入一个节点时触发,进入子节点会再一次触发这个事件(详见后文)。

  • mouseout:鼠标离开一个节点时触发,离开父节点也会触发这个事件(详见后文)。

  • mouseleave:鼠标离开一个节点时触发,离开父节点不会触发这个事件(详见后文)。

  • contextmenu:按下鼠标右键时(上下文菜单出现前)触发,或者按下“上下文菜单键”时触发。

  • wheel:滚动鼠标的滚轮时触发,该事件继承的是WheelEvent接口。

click事件指的是,用户在同一个位置先完成mousedown动作,再完成mouseup动作。因此,触发顺序是,mousedown首先触发,mouseup接着触发,click最后触发。

dblclick事件则会在mousedownmouseupclick之后触发。

mouseover事件和mouseenter事件,都是鼠标进入一个节点时触发。两者的区别是,mouseenter事件只触发一次,而只要鼠标在节点内部移动,mouseover事件会在子节点上触发多次。

setInterval

setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。

提示:1000 毫秒= 1 秒。

setInterval(code,millisec[,"lang"])

案例

 

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
  <style>
    div {
      width: 33px;
      height: 33px;
      background-image: url("./img/Actor01-Braver03.png");
      background-position-x: 0px;
      background-position-y: 0px;
      position: absolute;
      left: 0px;
      top: 0px;
    }
  </style>
</head>

<body>
  <div></div>
  <script>
    //   新建好要用的变量
    var actor, key;
    var speedX = 2,
      speedY = 2,
      x = 0,
      y = 0,
      count = 0,
      time = 10;
    //   初始化函数
    init();
    // 给actor绑定div元素  添加侦听事件  设置函数执行时间间隔
    function init() {
      actor = document.querySelector("div");/* 绑定div */
      document.addEventListener("keydown", mouseHandler);/* 鼠标按下事件及处理函数 */
      document.addEventListener("keyup", mouseHandler);/* 鼠标离开事件及处理函数 */
      setInterval(animation, 16);/* 设置函数处理时间间隔 */
    }

    //   帧频  帧

    // 60帧/秒
    //   1000/60=16.666666毫秒


//    鼠标事件处理函数
    function mouseHandler(e) {
        // 如果事件类型是鼠标按下时
      if (e.type === "keydown") {
        //   key不为空值时
        if (!key) {
            // 当事件键码为
          switch (e.keyCode) {
            //   键码为37 对应左方向键
            case 37:
            // 通过改变背景图位置实现图片往左位移
              actor.style.backgroundPositionY = "-33px";
              break;
            //  键码为38 对应顶部方向键 
            case 38:
              actor.style.backgroundPositionY = "-99px";
              break;
            //  键码为39 对应右方方向键 
            case 39:
              actor.style.backgroundPositionY = "-66px";
              break;
            //   键码为40 对应下部方向键
            case 40:
              actor.style.backgroundPositionY = "0px";
              break;
          }
        }
        // key绑定事件键码
        key = e.keyCode;
        console.log(e.keyCode);
        
      } else {
        //   无事件操作时key为underfined
        key = undefined;
        // actor回到初始状态
        actor.style.backgroundPositionX = "0px";
      }
    }
//    动态执行函数
    function animation() {
        // 无事件操作时返回不执行下面内容
      if (!key) return;
    //   actor方向操作函数
      changeActor();
    //   actor载体div移动函数
      actorMove();
    }
    //   防抖
    function changeActor() {
      //   因为考虑不能进入太快,当前函数原来是16毫秒进入一次。
      // 现在我们设置一个time,每10次进入一次,这样就造成每160毫秒进入一次,减缓图像改变速度
      // 这就是防抖
      time--;
      if (time > 0) return;
      time = 10;
      count++;
      if (count > 3) count = 0;
      actor.style.backgroundPositionX = -count * 32 + "px";

    }
// div移动函数
    function actorMove() {
      switch (key) {
        case 37:
          x -= speedX;
          break;
        case 38:
          y -= speedY;
          break;
        case 39:
          x += speedX;
          break;
        case 40:
          y += speedY;
          break;
      }
    //   绑定到actor定位实现移动
      actor.style.left = x + "px";
      actor.style.top = y + "px";
    }
  </script>
</body>

</html>

 

  分析

把需要的的元素绑定到变量,函数分别处理事件,判定条件执行动态操作,处理时间===time,小人方向===actor,小人移动===actor(div)对应定位,定位值绑定(x,y),小人(img)背景图位置绑定(speedX,speedY).

 

推荐阅读