single.php

JavaScriptのイベント追加コードでthisキーワードの使用

先回、WordPressサイトでアイキャッチ画像にマウスカーソルを重ねた時にプレビューが表示されるように、JavaScriptでコードを書いている時によく分からない部分でハマってしまった部分を備忘録として投稿します。

マウスオーバーでアイキャッチ画像をアニメーションGIFに置き換える

今回紹介するコードを使って、WordPressのアイキャッチ画像が表示されている箇所にマウスカーソルを重ねると、アニメーションGIFを使って、YouTubeのプレビューの様な表示ができるようになります。興味のある方は、別記事をご覧ください。

addEventListener での困った現象

実際に次のようなコードが上手く実行されなくてハマりました。DOMを使ってページ内の要素を取得し、マウスカーソルの動きで発動するイベントハンドラーを追加して、処理を行う簡単なものなのですが、ページ上で動作させると最終的に “_thumbs[i].style …” の部分が、実行されません。

//mouseleaveイベント追加
var _thumbs = document.getElementsByClassName("post-thumbnail");
_thumbs = Array.prototype.slice.call(_thumbs);

for (let i = 0; i < _thumbs.length; i += 1) {
  _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";
      var _url = "anime.gif";
      _thumbs[i].style.backgroundImage = "url(" + _url + ")";
      _thumbs[i].style.backgroundRepeat = "no-repeat";
      _thumbs[i].style.backgroundSize = "100%";
	
    }
  }
});

そもそも addEventListener メソッドを使って、要素にイベントを追加している部分で、追加した “function()” 内のコードに変数がある場合、その変数は、実行時に正しく処理されるのか、素直に疑問が残るところですが、私の書いたコードの場合、半分は正しく動作して、半分は動作しませんでした。特に “_thumbs[i]” は同じオブジェクトでも実行される個所とされない箇所があったため、原因に気が付くのに時間がかかりました。

thisキーワードで回避できた

JavaScriptには this キーワードがあります。Visual Basicの me キーワードのように、自身を表すキーワードです。

関数やメソッド、プロパティとして利用すれば、呼び出した元として振舞ってくれるのでコードの入力量を減らすのに役立ってくれます。

と、感覚的には分かっているのですが、今回のようにイベントハンドラーとして追加した関数での利用はよく分からないですが、次の様に修正して動作させることができました。

//mouseleaveイベント追加
var _thumbs = document.getElementsByClassName("post-thumbnail");
_thumbs = Array.prototype.slice.call(_thumbs);

for (let i = 0; i < _thumbs.length; i += 1) {
  _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";
      var _url = "anime.gif";
      this.style.backgroundImage = "url(" + _url + ")";
      this.style.backgroundRepeat = "no-repeat";
      this.style.backgroundSize = "100%";
	
    }
  }
});

後半部分のループ内で利用している “_thumbs[i]” をthisに置き換えた形になります。

まとめ

今回は短い記事ですが、JavaScript 内で、addEventListener を使ってイベントを追加した場合に、処理コード内で、getElementsByClassNameを使って取得したページ内の要素を使う場合に、正常に動作しない場合があります。

対処法として、thisキーワードが使える場合があるので抽象的なオブジェクトを置き換えることで正しく動作する場合があります。

addEventListener で要素にイベントハンドラーを追加した場合に、正しく動作しない方の参考になれば幸いです。

スポンサーリンク

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

コメントを残す

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