JavaScript
es6

最近jsで地味につまずいたところをメモしました

前置き

タイトル通り。ここ最近で地味につまずいたところをメモ(しただけ)

mouseoverとmouseout

以下のようなhtmlがあって、

index.html
<div>
<p>Javascript</p>
</div>

div要素にmouseover、mouseoutイベント登録すると・・・

test.js
const div = document.querySelector('div');
const p = document.querySelector('p');

div.addEventListener('mouseover', e => {
  div.style.transform = 'scale(1.5)';
});

div.addEventListener('mouseout', e => {
  div.style.transform = 'scale(1.0)';
});

divだけでなく、子要素であるpでもイベントが発火してしまう。。
stopPropagation()で止められるかと思ったが、これは子→親を止めるもので、
親→子は止めてくれない・・・

解決策

mouseover → mouseenter
mouseout → mouseleave

test.js
const div = document.querySelector('div');
const p = document.querySelector('p');

div.addEventListener('mouseenter', e => {
  div.style.transform = 'scale(1.5)';
});

div.addEventListener('mouseleave', e => {
  div.style.transform = 'scale(1.0)';
});

:ok_woman_tone1:

HTMLCollectionは配列じゃない!

そもそもHTMLCollectionとは?

test.js
document.getElementsByClassName('test'); //HTMLCollection

上記のように取得できるDOM要素ですね。
一見したところ、配列っぽいのですが、forEachとかfilterとか配列の便利メソッドが使用できません。。

ところがどっこい!下記だと配列のメソッドが使える!

test.js
document.querySelectorAll('.test'); //NodeList

これ!最近気づいて感動しました!!!
便利すぎて今まで私はどうやってDOM操作をしていたのか忘れました・・・
と思っていたのですが、調べてみるとchrome以外ではエラーになってしまうようです。。(知らなかった・・・ショック・・・)
ということで、配列のメソッド使いたい場合は、以下のような感じで配列に変換しましょう~~~

解決策

その1

test.js
[].slice.call(document.querySelectorAll('.test')).forEach(element => {
  console.log(element);
});

その2

test.js
Array.prototype.slice.call(document.querySelectorAll('.test')).forEach(element => {
    console.log(element);
});

:ok_woman_tone1:

まとめ(るまでもない)

もっと書けるかと思ったけど、案外書けることなかった・・・:angel_tone2:
勉強します・・・