文字

JSでfont-familyを変更[エラー解消]
公開:2020.09.11 更新:2020.09.11

事の始まりは昨日、深夜テンションで記事のフォントをいつでも変えられるボタンを実装しようと思った。

JSでのfont-familyへのアクセス

jsでcssのfont-familyを変更する基本構文は

HTML

<html>
<body>
<main class="contenttext">
<p>これは文です1</p>
<p>これは文です2</p>
<p>これは文です3</p>
<p>これは文です4</p>
<p>これは文です5</p>
</main>
</body>
</html>

JavaScript

let AP = document.getElementsByClassName("contenttext");
AP.style.fontFamily = "Noto Sans JP";

font-familyがfontFamilyになるので注意。キャメルケースという命名法らしいですね。font-sizeだとfontSize、font-weightだとfontWeightになります。

ただこのままだとエラーになります。エラーになりました、はい。

エラー文↓

Uncaught TypeError: Cannot set property 'fontFamily' of undefined
    at HTMLDivElement.

これはfontFamilyに関するエラーという訳ではなく<getElementsByClassName>に起因するものの様です。

getElementsByClassNameは返り値がHTMLCollectionと呼ばれる配列なので、getElementByIDで取れるエレメントとは違い、子オブジェクトに[style]が存在しない、というのが原因なようです。

これを解消する為に配列ではなく1オブジェクトとして取得する必要があります。

let AP = document.getElementsByClassName("contenttext");
AP[0].style.fontFamily = "Noto Sans JP";

該当classが一つだけならこれでCSS効きます。同名クラスが二つ以上ある場合には、一つ目の要素にしか反映されません。

参考

関数の文字色変更コードでCannot set property ‘color’ of undefined

Changing font-family on JS : can’t set property of undefined

おまけ(子要素にcss適用)

フォント替えたならpタグのmarginとか調整したいよね。っていうことで、子要素を変更する方法。

下記コードでclass=”contenttext”で取得した1番目のエレメントの子要素なpタグを取得できます。

let AP = document.getElementsByClassName("contenttext");
let BP = AP[0].getElementsByTagName("p");
BP[0].style.marginBottom = "5px";

ただ、getElementsByTagNameの返り値はまたもHTMLCollectionなので、このままでは1番目のpタグのcssしか変更されません。

今回のフォント変更ボタンでは記事の全段落を変更したいので、当然1行目だけでは冗談にしかなりません。

ということで最終的に下記コードになります。

let AP = document.getElementsByClassName("contenttext");
let BP = AP[0].getElementsByTagName("p");
for(let i=0;i<BP.length;i++){
  BP[i].style.marginBottom = "5px";
}

BP.lengthでfor文を作ることによって、pタグの数だけ同じ処理を繰り返せますので、変数iを使うことで全てのpタグに対して処理を行えますね。

参考

要素の取得方法まとめ(qlita)

おわり

私の場合はこれで解決でした。JSのオブジェクト的な使い方(本質的な動かし方)を知ってからは、こういったエラーもスムーズに直せるようになった気がします。何といっても楽しいですね。

JSなど、フロントエンド系の知識を学びたい方はyoutubeのしまぶーさんの動画をお勧めします。ちゃんと最新の技術を中心に発信されているので、多くを学べると思います。

それではそれでは。

おすすめ商品

一から勉強する際に使った教材

持っていると便利なHTML&CSS辞典

コメント

内容をご確認の上、送信してください。