マウスイベントをまとめてみた件

マウスイベントをまとめてみた件

マウスイベントを改めて学習してみることにしました。
マウスオーバーやマウスリーブイベントなど端的に学習することはあっても普段使わないイベントに対しての知識が偏りがあったのでことのついでに再学習します。以下マウスイベントの一覧です。

マウスイベント一覧

mouseenterマウスカーソルが要素に入り込んだ時
mouseleaveマウスカーソルが要素から出た時
mousemoveマウスカーソルが要素の上を移動した時
mouseoutマウスカーソルが要素の上から離れた時
mouseoverマウスカーソルが要素の上に乗った時
mouseupマウスボタンが離された時
mousedownマウスボタンが押された時
mousewheelマウスのホイールを使用した時

マウスイベントの挙動を確認してみよう。

イベントごとの挙動をコンソールを使い確認してみましょう。
試したソースは以下の通りになります。

<!-- 省略 -->
<ul class="p-mouse">
  <li class="p-mouse__area js-mouse">
    <div class="p-mouse__area__child"></div>
  </li>
  <li class="p-mouse__area js-mouse">
    <div class="p-mouse__area__child"></div>
  </li>
  <li class="p-mouse__area js-mouse">
    <div class="p-mouse__area__child"></div>
  </li>
</ul>
<!-- 省略 -->
.p-mouse {
  width: 100%;
  height: 50vh;
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  &__area {
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    flex: 0 0 33.33%;
    &:nth-child(1) {
      background: pink;
      .p-mouse__area__child {
        background: lightgray;
      }
    }
    &:nth-child(2) {
      background: lightyellow;
      .p-mouse__area__child {
        background: lightgreen;
      }
    }
    &:nth-child(3) {
      background: lightblue;
      .p-mouse__area__child {
        background: palegoldenrod;
      }
    }
    &__child {
      height: 50%;
      flex: 0 0 50%;
    }
  }
}
const mouseTargetObj = document.getElementsByClassName('js-mouse');

const eventList = [
  'mouseenter',
  'mouseleave',
  'mousemove',
  'mouseout',
  'mouseover',
  'mouseup',
  'mousedown',
  'mousewheel'
]

Array.from(mouseTargetObj).forEach(targetObj => {
  eventList.forEach(eventName => {
    targetObj.addEventListener(eventName, mouseEvents);
  })
})

function mouseEvents(event) {
  console.log(event.type);
}

コンソールに現在のイベントを発火させる簡単なテストコードですが、マウスイベントを追加した要素の中の子要素が検証のポイントとなっています。
子要素の中へ移動した時と子要素から外へ移動した時はマウスアウトとマウスオーバーのイベントが発火していますがマウスエンターとマウスリーブのイベントは発火していません。
マウスムーブはイベントを追加した親要素とその子要素ともに発火していることがわかります。

おまけでマウスストーカーを作ってみた。

先ほどのHTMLにコードを追加しマウスイベントを使いマウスストーカーをアレンジしてみました。対象のDOMにカーソルが重なるとストーカーが大きくなり対象のデータ属性のテキストを表示するようになっています。
以下サンプルコードです。

<!-- 省略 -->
<ul class="p-mouse">
  <li class="p-mouse__area js-hover" data-name="list01">
    <div class="p-mouse__area__child js-mouse-child"></div>
  </li>
  <li class="p-mouse__area js-hover" data-name="list02">
    <div class="p-mouse__area__child js-mouse-child"></div>
  </li>
  <li class="p-mouse__area js-hover" data-name="list03">
    <div class="p-mouse__area__child js-mouse-child"></div>
  </li>
</ul>
<div id="mouse-stalker" class="p-mouse-stalker"></div>
<!-- 省略 -->
.p-mouse-stalker {
  opacity: 0;
  user-select: none;
  pointer-events: none;

  &.js-stalker-on {
    width: 10px;
    height: 10px;
    display: flex;
    justify-content: center;
    align-items: center;
    background: rgba(#000, .8);
    opacity: 1;
    border-radius: 50%;
    position: fixed;
    top: -5px;
    left: -5px;
    transition: .3s ease;
    &.is-hover {
      width: 100px;
      height: 100px;
      color: #fff;
      top: -50px;
      left: -50px;
      transition: .3s ease;
    }
  }
}
//**************************************************//
//****************** mouseStalker ******************//
//**************************************************//
const stalker = document.getElementById('mouse-stalker');
window.addEventListener('load', function () {
  setMouseEvent();
});

//********* Mouse Event Set *********//
function setMouseEvent() {
  var pickupItems = document.getElementsByClassName('js-hover');
  Array.from(pickupItems).forEach(pickupItem => {
    pickupItem.addEventListener('mouseenter', stalkerHover);
    pickupItem.addEventListener('mouseleave', stalkerLeave);
  });
  window.addEventListener('mousemove', stalkerMove);
}
//********* End Mouse Event Set *********//

//********* Mouse Event Functions *********//

function stalkerMove(e) {
  if (!stalker.classList.contains('js-stalker-on')) {
    stalker.classList.add('js-stalker-on');
  }
  stalker.style.transform = 'translate3d(' + e.clientX + 'px, ' + e.clientY + 'px, 0)';
}

function stalkerHover(e) {
  stalker.classList.add('is-hover');
  stalker.innerHTML = '<span>' + this.dataset.name + '</span>';
}

function stalkerLeave(e) {
  stalker.classList.remove('is-hover');
  stalker.innerHTML = '';
}
//********* End Mouse Action Functions *********//

マウスエンターイベントの挙動のポイントはjsよりもcssでストーカーの対象となるDOMにpointer-events: none;を設定することです。

マウスイベントについてのまとめでした。