1. このページの目的
モバイル端末用ブラウザでツールチップ表示する。
画面上で発生するいろいろなイベント(モバイル端末テスト用)を検証する。
2. デモ
(1) a リンク (hover 擬似クラスで背景色を変える)
- モバイル端末の場合、タッチしてしばらくそのままにしていれば、hover がアクティブなままなる。
 
(2) p 要素 (title 属性によるツールチップ表示)
この行には、title 属性が設定されています。
- PCであればカーソルを重ねることで、title属性値がホバー表示される。
 - モバイル端末だと表示されない。
 
(3) p 要素 (title 属性によるツールチップ表示) に対し、モバイル端末用にCSSを記述する (media query + :focus 擬似クラス + ::after を利用)
この行には、title 属性が設定されています。
- CSSを追記したことにより、モバイル端末でも「タッチ」するとツールチップが表示される。もう一度タッチすると消える。
 
(4) モバイル端末の場合、クリックするとツールチップを表示する (JavaScript 利用)
この行には、title 属性が設定されています。
- モバイル端末の場合、もう一度クリックするとツールチップは消える。
 - PC の場合は title 属性により、ホバーするとツールチップが表示される。
 
(5) Touch events
この行には、touch イベントハンドラが設定されています。
- タッチすると、発生したイベント名が表示される。
 - PC でクリックしてもイベントは発生しない。
 
3. ソースコード
(1)
HTML
<p><a class="type1" href=".">この行には、hover が設定されています。</a></p>
      CSS
.type1:hover {
  background-color: yellow;
}
      (2)
HTML
<p title="タイトル属性値です(2)!">この行には、title 属性が設定されています。</p>
      (3)
HTML
<p class="type3" title="タイトル属性値です(3)!" tabindex="0">この行には、title 属性が設定されています。</p>
      CSS
@media (pointer: coarse), (hover: none) {
  .type3[title] {
    position: relative;
    display: inline-flex;
    justify-content: center;
  }
  .type3[title]:focus::after {
    content: attr(title);
    position: absolute;
    top: 90%;
    color: #000;
    background-color: #fff;
    border: 1px solid;
    width: fit-content;
    padding: 3px;
  }
}
      (4)
HTML
<p class="type4" title="タイトル属性値です(4)!">この行には、title 属性が設定されています。</p>
      CSS
.type4 {
  position: relative;
}
.type4 .title {
  position: absolute;
  top: 18px;
  background: white;
  border: 1px solid gray;
  padding: 5px;
  left: 0;
  white-space: nowrap;
}
      JavaScript
window.addEventListener('DOMContentLoaded', (event) => {
  const isMobile = (() => {
    const mediaQueryList = window.matchMedia("(pointer:coarse), (hover:none)");
    return mediaQueryList.matches;
  })();
  const setToolTip = () => {
    document.querySelectorAll('p.type4[title]').forEach((elm) => {
      elm.addEventListener('click', function(event) {
        const titleElms = this.querySelectorAll('.title');
        if (titleElms.length) {
          titleElms.forEach((elm) => {
            elm.remove();
          });
        } else {
          const title = this.getAttribute('title');
          if (title.length) {
            const spanElm = document.createElement('span');
            spanElm.classList.add('title');
            spanElm.textContent = title;
            this.appendChild(spanElm);
          }
        }
      });
    });
  };
  if (isMobile) {
    setToolTip();
  }
});
      (5)
HTML
<p id="elm5">この行には、touch イベントハンドラが設定されています。</p>
<p id="output5"></p>
      JavaScript
window.addEventListener('DOMContentLoaded', (event) => {
  const outputElm5 = document.querySelector('#output5');
  const touchElm = document.querySelector('#elm5');
  touchElm.addEventListener('touchstart', (event) => {
    console.log('touchstart');
    outputElm5.innerHTML += 'btouchstart';
  }, {passive:true});
  touchElm.addEventListener('touchend', () => {
    console.log('touchend');
    outputElm5.innerHTML += '<br>touchend';
  });
  touchElm.addEventListener('<br>touchcancel', () => {
    console.log('touchcancel');
    outputElm5.innerHTML += '<br>touchcancel';
  });
  touchElm.addEventListener('touchmove', () => {
    console.log('touchmove');
    outputElm5.innerHTML += '<br>touchmove';
  }, {passive:true});
});