single.php

WordPressのアイキャッチ画像をマウスのホバーでアニメーションさせる(スマホ対応版)

先回、YouTubeや動画の視聴サイトで、サムネイル画像にマウスカーソルを重ねた時にプレビューが表示されるように、アイキャッチ画像を動かす仕組みをタッチスクリーンなどに対応したスマホ対応版として投稿します。

マウスオーバーでプレビューさせる

先回、アニメーションGIFを使って、こんな感じでサイトにプレビュー表示の仕組みを作ってみた訳です。

スマートフォンやタブレット用にイベントを変更

タッチスクリーンが搭載されたスマホやタブレットでもアイキャッチ画像を動かそうとする場合、マウスのホバー(mouseover)とカーソルが離れる(mouseleave)イベントに近い、touchstartとtouchendイベントが用意されているので、そこに置き換えていきます。

仕組み的には、マウスカーソルがアイキャッチ画像のエリアに入ってきた(mouseover)のイベントで、画像を非表示にして用意しておいたアニメーションGIFに入れ替えます。

詳しいコードの内容は、先回の記事をご覧ください。

今回変更するのは、mouseoverイベントの部分を以下のように変更します。

//touchstartイベント追加
_thumbs[i].addEventListener('touchstart', function() {
  var _src = "";
  _images = this.getElementsByTagName("img");
  _images = Array.prototype.slice.call(_images);
			
  for (let j = 0; j < _images.length; j += 1) {
    var _url = "https://sample.com/wp-content/uploads/gif/sample-1.gif";
    this.style.backgroundImage = "url(" + _url + ")";
    this.style.backgroundRepeat = "no-repeat";
    this.style.backgroundSize = "100%";
  }
});

`同じように、指が離れた場合にアニメーションGIFを非表示にしてアイキャッチ画像と入れ替えます。

mouseleaveイベントの部分を以下のように変更します。

//touchendイベント追加
_thumbs[i].addEventListener('touchend', function() {
  var _images = _thumbs[i].getElementsByTagName("img");
  _images = Array.prototype.slice.call(_images);

  for (let j = 0; j < _images.length; j += 1) {
    _images[j].style.visibility = "visible";
    this.style.backgroundImage = "";
  }
});

これで、指がアイキャッチ画像のエリアに触れるとアニメーションGIFが再生され離すと、アイキャッチ画像に戻るようになります。

後は、スマホ(iPhoneやAndroid)を判定して、追加するイベントを切り替えることで両方のデバイスに対応することができます。

私が良く使うのは、こんな感じの判定。(他にも方法はあるので、お好みで)

iPhoneはともかく、Androidやその他のデバイスは日々追加されていくので確実な方法はありません。この方法でも9割くらいはカバーできている(はず)です。

function _issmartphone() {
  if (navigator.userAgent.match(/iPhone|Android.+Mobile/)) {
    return true;
  } else {
    return false;
  }
}

全体的なコードは次のようになります。_issmartphone関数で判定して、イベント名を変更しています。

window.onload = function() {
  var _thumbs = document.getElementsByClassName("post-thumbnail");
  _thumbs = Array.prototype.slice.call(_thumbs);
  var _phone = _issmartphone();

  for (let i = 0; i < _thumbs.length; i += 1) {
    var _images = _thumbs[i].getElementsByTagName("img");
    _images = Array.prototype.slice.call(_images);
		
    for (let j = 0; j < _images.length; j += 1) {\
      if(_phone == false) {
        //mouseoverイベント追加
        _images[j].addEventListener('mouseover', function() {
          this.style.visibility = "hidden";
        });
      } else {
        //touchstartイベント追加
        _images[j].addEventListener('touchstart', function() {
          this.style.visibility = "hidden";
        });
      }
    }

    if(_phone == false) {
		
      //mouseoverイベント追加
      _thumbs[i].addEventListener('mouseover', function() {
        var _src = "";
        _images = this.getElementsByTagName("img");
        _images = Array.prototype.slice.call(_images);
			
        for (let j = 0; j < _images.length; j += 1) {
          var _url = "https://sample.com/wp-content/uploads/gif/sample-1.gif";
          this.style.backgroundImage = "url(" + _url + ")";
          this.style.backgroundRepeat = "no-repeat";
          this.style.backgroundSize = "100%";
        }
      });

      //mouseleaveイベント追加
      _thumbs[i].addEventListener('mouseleave', function() {
        var _images = _thumbs[i].getElementsByTagName("img");
        _images = Array.prototype.slice.call(_images);
		
        for (let j = 0; j < _images.length; j += 1) {
          _images[j].style.visibility = "visible";
          this.style.backgroundImage = "";
        }
      });

    } else {

      //touchstartイベント追加
      _thumbs[i].addEventListener('touchstart', function() {
        var _src = "";
        _images = this.getElementsByTagName("img");
        _images = Array.prototype.slice.call(_images);
			
        for (let j = 0; j < _images.length; j += 1) {
          var _url = "https://sample.com/wp-content/uploads/gif/sample-1.gif";
          this.style.backgroundImage = "url(" + _url + ")";
          this.style.backgroundRepeat = "no-repeat";
          this.style.backgroundSize = "100%";
        }
      });

      //touchendイベント追加
      _thumbs[i].addEventListener('touchend', function() {
        var _images = _thumbs[i].getElementsByTagName("img");
        _images = Array.prototype.slice.call(_images);
		
        for (let j = 0; j < _images.length; j += 1) {
          _images[j].style.visibility = "visible";
          this.style.backgroundImage = "";
        }
      });
    }
  }
}

function _issmartphone() {
  if (navigator.userAgent.match(/iPhone|Android.+Mobile/)) {
    return true;
  } else {
    return false;
  }
}

手強い長押し判定

touchstartとtouchendイベントを追加して、スマホやタブレットでもアイキャッチ画像を触れている間、アニメーションGIFを表示することができました。

しかし、タッチスクリーンを特有の長押し判定があり「画像を保存」などのメニューが表示されるようになってしまい、使い辛くなります。

長押しした際のメニューは、oncontextmenu イベントを拾って false を返却することで無効にすることができます。

window.oncontextmenu = function(event) {
  event.preventDefault();
  event.stopPropagation();
  return false;
};

しかし、このまま実装するとリンクや他の画像でもメニューが表示されなくなるので、次の様にアイキャッチ画像の要素だけに変更を行います。

//contextmenuイベント追加
_thumbs[i].addEventListener('contextmenu', function() {
  event.preventDefault();
  event.stopPropagation();
  return false;
})

出来上がったコードは次のようになります。

window.onload = function() {
  var _thumbs = document.getElementsByClassName("post-thumbnail");
  _thumbs = Array.prototype.slice.call(_thumbs);
  var _phone = _issmartphone();

  for (let i = 0; i < _thumbs.length; i += 1) {
    var _images = _thumbs[i].getElementsByTagName("img");
    _images = Array.prototype.slice.call(_images);
		
    for (let j = 0; j < _images.length; j += 1) {\
      if(_phone == false) {
        //mouseoverイベント追加
        _images[j].addEventListener('mouseover', function() {
          this.style.visibility = "hidden";
        });
      } else {
        //touchstartイベント追加
        _images[j].addEventListener('touchstart', function() {
          this.style.visibility = "hidden";
        });
      }
    }

    if(_phone == false) {
		
      //mouseoverイベント追加
      _thumbs[i].addEventListener('mouseover', function() {
        var _src = "";
        _images = this.getElementsByTagName("img");
        _images = Array.prototype.slice.call(_images);
			
        for (let j = 0; j < _images.length; j += 1) {
          var _url = "https://sample.com/wp-content/uploads/gif/sample-1.gif";
          this.style.backgroundImage = "url(" + _url + ")";
          this.style.backgroundRepeat = "no-repeat";
          this.style.backgroundSize = "100%";
        }
      });

      //mouseleaveイベント追加
      _thumbs[i].addEventListener('mouseleave', function() {
        var _images = _thumbs[i].getElementsByTagName("img");
        _images = Array.prototype.slice.call(_images);
		
        for (let j = 0; j < _images.length; j += 1) {
          _images[j].style.visibility = "visible";
          this.style.backgroundImage = "";
        }
      });

    } else {

      //contextmenuイベント追加
      _thumbs[i].addEventListener('contextmenu', function() {
        event.preventDefault();
        event.stopPropagation();
        return false;
      });

      //touchstartイベント追加
      _thumbs[i].addEventListener('touchstart', function() {
        var _src = "";
        _images = this.getElementsByTagName("img");
        _images = Array.prototype.slice.call(_images);
			
        for (let j = 0; j < _images.length; j += 1) {
          var _url = "https://sample.com/wp-content/uploads/gif/sample-1.gif";
          this.style.backgroundImage = "url(" + _url + ")";
          this.style.backgroundRepeat = "no-repeat";
          this.style.backgroundSize = "100%";
        }
      });

      //touchendイベント追加
      _thumbs[i].addEventListener('touchend', function() {
        var _images = _thumbs[i].getElementsByTagName("img");
        _images = Array.prototype.slice.call(_images);
		
        for (let j = 0; j < _images.length; j += 1) {
          _images[j].style.visibility = "visible";
          this.style.backgroundImage = "";
        }
      });
    }
  }
}

function _issmartphone() {
  if (navigator.userAgent.match(/iPhone|Android.+Mobile/)) {
    return true;
  } else {
    return false;
  }
}

まとめ

WordPressの記事で設定されているアイキャッチ画像を、JavaScriptとアニメーションGIFを使ってYouTubeのプレビューのように動作させる仕組みをスマホでも動作するように改良してみました。

画像に指を触れている間、アニメーションGIFが再生されるのででページにイベント的な動きを追加することができます。

WordPressのアイキャッチ画像をタッチしたらプレビュー動画を再生したい人の参考になれば幸いです。

スポンサーリンク

最後までご覧いただき、ありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です