個人サイト制作:サイトマップへ戻る

個人サイトでよく使うJavaScript

このあたりから敷居が上がってくるんですよね。 私も学生時代は大苦戦しました。 HTML+CSSだけなら、さほどでもないんですよ。─ CSSも凝ってくるとややこしいけど。 ─ JavaScriptが絡んでくると実装に手間がかかってきます。

私の場合は学生時代に組んだものがコード資産として大量に残っているから良いけど、個人サイトをイチから作ろうと した場合、JavaScriptのあたりがキツいという人はいっぱいいると思うんですよね。
そういう意味でも、個人サイトを作るなら手書きではなくて手軽なウェブサイトビルダーを使うのが良いと思います。
Google SitesかBloggerが私からのお勧めです。

このページに関する注意事項

当Webサイト作成者は、例示を目的としてマークアップ及びプログラミング例を提供しており、明示または黙示にかかわらず、いかなる責任も負わないものとします。
このページは、説明されているマークアップ及びプログラミング言語、手順を作成およびデバッグするために使用される各種ツールに読者が精通していることを前提にしています。
このページは、特定の機能を説明するのに役立つ可能性がありますが、当Webサイト作成者がこれらの例を変更した上で、特定の要件を満たすために追加の機能を提供したり、システムを構築したりすることはできません。
加えて、この例の手順に従う場合は、読者の各種ファイルを事前にバックアップすることを推奨いたします。

動作を決めているJavaScript

乱用は禁物だと私は思っているんだけど、必要と思われるところに目立たぬよう小さな機能が実装されていたりすると、閲覧者にとって便利なツールになるんですよ。
一方、無理にフロントエンドで実装するよりサーバーサイドスクリプトでやってしまったほうがラクと思われる機能もあります。

動的なコンテンツの追加

JavaScriptを使うと、Webページに動的なコンテンツを追加できます。
例えば、ボタンをクリックすると新しい情報が表示されたり、画像が切り替わったりするのは、JavaScriptのおかげです。

ユーザーインタラクションの向上

JavaScriptを使って、ユーザーの操作に応じてリアルタイムに反応することができます。
フォームに入力した内容の確認や、リアルタイムの検索結果表示など。

データの操作

JavaScriptは、Webページ上でデータを操作するためにも使われます。
ユーザーから入力されたデータを収集して、サーバーに送信したり、サーバーから取得したデータを表示することができます。

アニメーションの実装

JavaScriptを使えば、Webページ上でアニメーションを実装することもできます。
スクロールに応じてエフェクトが発生したり、要素がフェードイン・アウトするなど。

これはお勧めですよ。
さりげなく実装しておけば、一気に映えるサイトにできます。

JavaScriptも外部化するのがお勧めです

JavaScriptもCSSと同じで、こうやって外部化するのを強くお勧めします。
CSSも凝ってくるとものすごいコードになってきますし、それに加えてJavaScriptまでhtml内部に入れていると、後から地獄ですよ?
コードの関連付けまでグチャグチャになってしまうと、もう更新の継続は現実的ではありません。
柔軟な仕様変更にも対応できるよう、初めから仕込んでおくのがお勧めです。


<!--JavaScript-->
    <script src="script/feinfade.js"></script>
    <script src="script/collapsible.js"></script>
    <script src="script/underline.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.6.347/pdf.min.js"></script>
    <script src="script/pdf.js" defer></script>
    

これまたモノと諸事情によってはhtml内部にそのままJavaScriptを書くこともあるんです。
もうそこにしか使わないことが分かっているような、特殊な動きを作ったりとか。
でもそうでないものは基本原則として外部化するようにしています。
しっかり説明しましょうかね…そこそこコードを書ける人でも個人サイトが続かなくなる、最たる原因だと私は思ってる。

JavaScriptやCSSを外部化するメリット

コードの再利用性

JavaScriptやCSSを外部ファイルに保存すると、同じファイルを複数のページで使い回すことができます。
これにより、一度書いたコードを何度も書き直す必要がなくなり、効率が向上します。
「再利用性の向上」は、外部化の大きなメリット
これほんと強いですよ?
一か所書いてしまえば、そのコードをいくらでも使い回せる。

コードの保守性

外部ファイルにコードを分離すると、HTMLファイルがすっきりして見やすくなります。
こうすることで「保守が容易になり、バグの発見や修正が簡単に」なります。
特に大規模なプロジェクトでは、このメリットが非常に大きいです。
さらに言うと、個人サイトみたいな小規模プロジェクトでも同じですよ?
保守性をきちんとしておけば、楽しい作業だけに没頭できるのですから。

ページの読み込み速度

ブラウザは外部ファイルをキャッシュ(保存)することで、次回以降の読み込みを高速化します。
かなり長大なコードじゃないと変化は実感しにくいものの、「ユーザー体験が向上し、ページの表示速度が速くなる」
ページの読み込みが速いと、ユーザーが快適にサイトを利用できます。
まぁ…ここはね。キャッシュがどうの以前に、広告が表示される個人サイトが多いので😥
やるならさりげなく置いたほうが利益にも繋がると、私は過去の経験から学んでいるんですけどね?
なぜユーザーの邪魔になるような広告の置き方をするのか。

作業の分担と協力

個人サイトには関係ないけど…─ いやむしろ個人サイトレベルで複数人作業なんか下手にやると、トラブルの遠因になりますよ! ─
複数の開発者がプロジェクトに関わる場合、外部ファイルにすることで「作業の分担がしやすくなり」、各自の役割が明確になります。
フロントエンド開発者がHTMLとCSSを、バックエンド開発者がJavaScriptを担当するなど、効率的に協力して開発が進められます。

セキュリティの向上

JavaScriptやCSSを外部ファイルに分けることで、「コードの管理が容易に」なり、不正な変更を防ぐための対策がしやすくなります。
重要なコードや機密情報を適切に保護することが可能になります。
自分でもワケが分からなくようなコードは、初めから置かない。
これでしょ。

むしろ、コードの外部化は必須かもね?

JavaScriptやCSSを外部化することで、「再利用性の向上」「保守性の向上」「ページの読み込み速度の向上」「作業の分担と協力のしやすさ」「セキュリティの向上」といった多くのメリットがあります。
これにより、効率的で安全かつ、長期継続可能な個人サイト制作が可能になります。

参考サイト

The relationship between HTML, CSS and JavaScript explained by building a city

freeCodeCamp(フリーコードキャンプ)は、2014年にクインシー・ラロン(Quincy Larson)によって設立された非営利団体です。
この組織は、無料のオンラインリソースを使って、人々を技術のキャリアに導くことを目的としており、学習プラットフォーム、チャットルーム、メディア出版物などを提供し、誰でもアクセスしやすい学習環境を提供しています。
特に、HTML、CSS、JavaScriptなどの基本的なプログラミングスキルを学ぶためのチュートリアルやプロジェクトが充実しており、無料で提供されています。
また、学習者がプロジェクトを通じてスキルを磨き、無料の認定資格を取得できるようにサポートしてるんですよね。
Mozilla以外にもすごい組織はいっぱいありますよ。
freeCodeCampは、多くのボランティアと寄付者の支援を受けて運営されており、世界中で利用されています。

画像のフェードインとフェードアウト

グラスタの場所一覧表ページでは、ユーザーのスクロールに従って画像がフェードイン&フェードアウトするよう、効果を付けています。
これについて説明しましょう。
CSSとJavaScript、双方が関係しあって、HTMLの画像に作用するようになっています。

この効果、既にCSSとJavaScriptは外部化されているので、他のいろんなページに使うことができますよ。
例えば魚コーナーに使うこともできるし、カエル写真集に使ったっていいし。
ここにこうやって解説ページを作っておくことで、私もコードを整理しやすいのです。
自分のサイトを見ればコードが解説付きで保管されていることになるからね。

画像のフェードインとフェードアウト(CSS)

「fade-in-out」クラスを持つ画像があります。
これが「visible」クラスが追加されたときにフェードインし、「visible」クラスが削除されたときにフェードアウトするようになっています。


/* フェードイン・フェードアウトのアニメーション */
img.fade-in-out {
    opacity: 0;
    transition: opacity 1s ease-in-out;
}

img.fade-in-out.visible {
    opacity: 1;
}
        

opacity: 0;
画像の透明度を0に設定します。
画像は完全に見えなくなります。

transition: opacity 1s ease-in-out;
透明度が変化する際のアニメーションの設定です。
1秒かけて透明度が変わり、変化の速度が滑らかに始まり、滑らかに終わるようにします。
ここは迷ってますね。1秒でも良いんだけど、0.5秒とかでも良いかもしれない。

img.fade-in-out.visible {
これは、「fade-in-out」クラスに加えて「visible」クラスが付いた「img」タグに対して、スタイルを適用することを示しています。

opacity: 1;
画像の透明度を1に設定します。
画像が完全に見えるようになります。

画像のフェードインとフェードアウト(JavaScript)

このコードは次のような動きを実現するためのものです。

  1. ページが読み込まれた後とスクロールされたときに、特定の画像が表示領域内にあるかどうかをチェック。
  2. 表示領域内にある場合は「visible」クラスを追加。
  3. そうでない場合は削除する。

このようにスクリプトを組めば、画像がフェードイン・フェードアウトする効果が作れるんですよね。
どこまで丁寧に解説すべきか分からないけど、とりあえずササっと1行ずつやっていきましょうか。

画像のフェードイン+アウトのアニメーションを作るfeinfade.js


document.addEventListener('DOMContentLoaded', function() {
    const images = document.querySelectorAll('img.fade-in-out');
    const checkVisibility = () => {
        images.forEach(image => {
            const rect = image.getBoundingClientRect();
            const imageCenter = rect.top + rect.height / 2;
            const windowHeight = window.innerHeight;

            if (imageCenter < windowHeight * 0.85 && imageCenter > windowHeight * 0.15) {
                image.classList.add('visible');
            } else {
                image.classList.remove('visible');
            }
        });
    };

    checkVisibility();
    document.addEventListener('scroll', () => {
        requestAnimationFrame(checkVisibility);
    });
});
        

document.addEventListener('DOMContentLoaded', function() {
HTMLドキュメントが完全に読み込まれたときに実行される関数を設定します。
もうちょっと詳しく言うと、このコードはDOMContentLoadedというイベントリスナーを設定しています。
つまり、DOMContentLoadedイベントが発生したときに実行される関数を指定しているということです。


document.addEventListener('DOMContentLoaded', function() { ... });
        

この部分は、HTMLドキュメントが完全に読み込まれ、解析されてDOMツリーが構築されたときに実行される関数を設定しています。
つまり、ページの基本的な構造が整った時点で、指定した関数が実行されるようになります。

const images = document.querySelectorAll('img.fade-in-out');
クラス名が「fade-in-out」の<img>タグをすべて選択し、それらを「images」という定数に格納します。

const checkVisibility = () => {
画像の表示状態をチェックする関数「checkVisibility」を定義します。

images.forEach(image => {
「images」に含まれるすべての画像に対して、順番に処理を行うためのループを開始します。
アナザーエデンで「ループ攻略」なんてものがあったでしょう?
あれですよアレ(笑)

const rect = image.getBoundingClientRect();
画像の位置とサイズを取得し、それを「rect」という定数に格納します。

const imageCenter = rect.top + rect.height / 2;
画像の中心位置を計算し、それを「imageCenter」という定数に格納します。
ここで、「2」が使われている理由は、画像の中心位置を計算するためです。
具体的には、「rect.top」は画像の上端の位置を示し、「rect.height」は画像の高さを示します。
画像の中心位置を求めるためには、画像の上端から画像の高さの半分の位置を足す必要があります。
こうすることで、画像の中央の位置が得られます。
例えば、画像の上端が100ピクセルの位置にあり、画像の高さが200ピクセルの場合、画像の中心位置は次のように計算されます。


const imageCenter = 100 + 200 / 2; // 100 + 100 = 200
        

このようにして、画像の中心位置を正確に求めることができます。

const windowHeight = window.innerHeight;
ブラウザウィンドウの高さを取得し、それを「windowHeight」という定数に格納します。

if (imageCenter < windowHeight * 0.85 && imageCenter > windowHeight * 0.15) {
画像の中心がウィンドウの上から15%と85%の間にあるかどうかをチェックしています。
ここも迷ってますね。
10%と90%でも良いかもしれないけど、あまり数が大きいと効果が分かりにくいかもしれない。

image.classList.add('visible');
条件が満たされた場合、画像に「visible」というクラスを追加します。

} else {
条件が満たされなかった場合の処理を開始します。

image.classList.remove('visible');
条件が満たされなかった場合、画像から「visible」というクラスを削除します。

}
「if」文の終了を示します。
こういうところなんですよ…学生時代は、こういうところをテキトーにやってて、いろんなところでエラーが出たり動かなかったりするサイトを量産してました。
1行ずつ書いてるノートを作っておけば良かったんだよね。
スクリプトを書いたら書きっぱなしで、至るところに放り出していました。
それが後々になって管理し切れなくなり、個人サイトの挫折への繋がっていたのです。
隅っこのカッコの一つまで意識してね。
完璧じゃなくても、こうして自分含めた多方面にメリットが出るよう、やっていきたいものです。

});
「forEach」ループの終了を示します。

};
「checkVisibility」関数の終了を示します。

checkVisibility();
ページが読み込まれたときに「checkVisibility」関数を実行します。

document.addEventListener('scroll', () => {
ページがスクロールされたときに実行される関数を設定します。

requestAnimationFrame(checkVisibility);
ブラウザが次に画面を再描画するタイミングで「checkVisibility」関数を実行するようにリクエストします。

});
スクロールイベントのリスナーの終了を示します。
「リスナー」という言葉は、JavaScriptにおいて特定のイベントが発生したときに実行される関数のことを指します。例えば、ボタンがクリックされたときやページがスクロールされたときに特定の処理を実行するために使われます。
上の方で、addEventListenerメソッドを使ってイベントリスナーを設定していますよね。

});
「DOMContentLoaded」イベントのリスナーの終了を示します。

DOMContentLoaded

DOMContentLoadedは、HTML文書が完全に読み込まれ、解析されてDOMツリーが構築されたときに発生するイベントのことです。
このイベントは、画像やスタイルシートなどの外部リソースの読み込みが完了する前に発生します。
つまりですねー…
「DOMContentLoaded」イベントというのは、ページの基本的な構造が整った時点で発生し、スクリプトがDOM要素にアクセスできるようになっているのです。
これを使えば、ページの初期化処理を迅速に行うことができます。
例えば、ページが完全に読み込まれるのを待たずに、ボタンのクリックイベントを設定したり、特定の要素を操作したりする場合に便利です。
ここでは画像を操作しているんですよね。

折り畳みエリア

折り畳みを始めとする動的なものは、SEOとしてはあーんまり望ましくないんだよね。
でもグラスタ表はすぐに出てきているわけで。
では、ここからは「リアル世界のプログラムにおける、ループ攻略」について書きましょうか!

折り畳みエリア(CSS)

基本的なものだから特徴らしきものはないんだけど、可能な限り丁寧に解説していきますかね。
テーブルタグに使っているもののほうが難しいと思う

折り畳みエリアを作るcollapsible.css


.collapsible {
  background-color: #f1f1f1;
  color: #444;
  cursor: pointer;
  padding: 10px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  font-family: 'Noto Sans JP', sans-serif;
  transition: background-color 0.3s ease;
   }

.collapsiblecontent {
  padding: 0 10px;
  max-height: 0;
  overflow: hidden;
  background-color: #f9f9f9;
  transition: max-height 0.3s ease, opacity 0.3s ease;
  opacity: 0;
   }

.collapsiblecontent.show {
  max-height: 2000px;
  opacity: 1;
   }
            

.collapsible {
クラス名「collapsible」を持つ要素に適用されるスタイルの開始を示しています。

background-color: #f1f1f1;
背景色を淡い灰色(#f1f1f1)に設定しています。

color: #444;
文字の色を濃い灰色(#444)に設定しています。

cursor: pointer;
マウスカーソルが指の形になり、クリックできることを示しています。
こういうのけっこう大切にしてます。
クリックできるかどうか分からなかったりするとちょっとね。

padding: 10px;
要素の内側に10ピクセルの余白を追加しています。

width: 100%;
要素の幅を100%に設定しています。親要素の幅に対して100%です。

border: none;
要素の枠線をなくしています。

text-align: left;
テキストを左揃えにしています。

outline: none;
要素の外枠(フォーカス時に表示される枠)をなくしています。

font-size: 15px;
フォントサイズを15ピクセルに設定しています。

font-family: 'Noto Sans JP', sans-serif;
フォントを「Noto Sans JP」に設定しています。このフォントがない場合は、代わりに「sans-serif」が使用されます。

transition: background-color 0.3s ease;
背景色が変更されるときに0.3秒かけて滑らかに変化するようにしています。

.collapsiblecontent {
これは、クラス名「collapsiblecontent」を持つ要素に適用されるスタイルの開始を示しています。

padding: 0 10px;
要素の内側に左右10ピクセルの余白を追加していますが、上下の余白はありません。

max-height: 0;
要素の最大高さを0に設定しています。これにより、デフォルトで要素が表示されません。

overflow: hidden;
要素の内容がはみ出した場合に隠す設定をしています。

background-color: #f9f9f9;
背景色を薄い灰色(#f9f9f9)に設定しています。

transition: max-height 0.3s ease, opacity 0.3s ease;
最大高さと透明度が変更されるときに0.3秒かけて滑らかに変化するようにしています。

opacity: 0;
要素を完全に透明に設定しています。

.collapsiblecontent.show {
クラス名「collapsiblecontent」を持ち、さらにクラス「show」を持つ要素に適用されるスタイルの開始を示しています。

max-height: 2000px;
要素の最大高さを2000ピクセルに設定しています。
これちょっと迷ってるんだよね。
2000も必要かどうかは今後による。

opacity: 1;
要素を完全に表示する設定です。

折り畳みエリア(JavaScript)

では、ここでループについて書いていきます。
ループ攻略ですね!

折り畳みエリアを作るcollapsible.js


document.addEventListener("DOMContentLoaded", function() {
    var coll = document.getElementsByClassName("collapsible");
    for (var i = 0; i < coll.length; i++) {
        coll[i].addEventListener("click", function() {
            this.classList.toggle("active");
            var content = this.nextElementSibling;
            if (content.classList.contains("show")) {
                content.classList.remove("show");
                content.style.maxHeight = null;
                this.innerHTML = 'タップして開く ▼';
            } else {
                content.classList.add("show");
                content.style.maxHeight = content.scrollHeight + "px";
                this.innerHTML = 'タップして閉じる ▲';
            }
        });
    }
  });
  

document.addEventListener("DOMContentLoaded", function() {
HTMLドキュメントがすべて読み込まれた後に指定された関数が実行されるように設定しています。
これがあることでページの要素にアクセスできるようになります。

var coll = document.getElementsByClassName("collapsible");
クラス名「collapsible」を持つすべての要素を取得し、変数 coll に格納しています。

for (var i = 0; i < coll.length; i++) {
取得したすべての「collapsible」要素に対してループを開始する行です。
変数 i が0から coll の長さまで繰り返されます。

coll[i].addEventListener("click", function() {
それぞれの「collapsible」要素に対して、クリックイベントリスナーを追加しています。
要素がクリックされたときに指定された関数が実行されます。

this.classList.toggle("active");
クリックされた要素のクラスリストに「active」クラスを追加または削除します。
すでに「active」クラスがあれば削除し、なければ追加します。

var content = this.nextElementSibling;
クリックされた要素の次の兄弟要素(次のタグ)を取得し、変数 content に格納します。
分かりにくいけど、こういうのは普通、折りたたみ部分の内容を指すことが多いです。
私はいつもそういう感じで書いてますね。

if (content.classList.contains("show")) {
取得した要素が「show」クラスを持っているかどうかをチェックします。
持っていれば折りたたみが開いている状態です。

content.classList.remove("show");
要素から「show」クラスを削除し、折りたたみを閉じる状態にします。

content.style.maxHeight = null;
要素の最大高さをリセットし、折りたたみを閉じる状態にします。

this.innerHTML = 'タップして開く ▼';
クリックされたボタンのテキストを「タップして開く ▼」に変更します。
こういう細かい変化はページ全体ができてからやっていけばいいけど、割と大切にしてます。

} else {
上記の条件が満たされない場合、すなわち要素が「show」クラスを持っていない場合(折りたたみが閉じている状態)に実行されます。

content.classList.add("show");
要素に「show」クラスを追加し、折りたたみを開く状態にします。

content.style.maxHeight = content.scrollHeight + "px";
要素の高さをその内容の高さに設定し、折りたたみを開きます。

this.innerHTML = 'タップして閉じる ▲';
クリックされたボタンのテキストを「タップして閉じる ▲」に変更します。

}
条件文(if-else文)の終了を示します。

});
クリックイベントリスナーの終了を示します。

}
ループの終了を示します。
ループ攻略が終わった状態です😆ww

});
ドキュメント全体が読み込まれたときに実行される関数の終了を示します。

ヘッダーのロゴ画像スクロール

コードに合う解説文の出庫待ち


document.addEventListener("DOMContentLoaded", function() {
    const headerImage = document.querySelector('.header-image'); // ヘッダー画像の要素を取得

    headerImage.style.opacity = 0; // 初期状態で透明に設定
    headerImage.style.transform = 'translateX(100%)'; // 初期状態で右にオフセット

    setTimeout(() => {
        headerImage.style.opacity = 1; // 透明度を1に設定して表示
        headerImage.style.transform = 'translateX(0)'; // オフセットを0にして元の位置に戻す
        console.log("Header image is visible"); // コンソールにメッセージを表示
    }, 100); // 100ミリ秒後に実行
});

ヘッダーのロゴ画像スクロール

コードに合う解説文の出庫待ち


サイトマップ

アナザーエデン関連ページ・サイトマップ

アナザーエデンの強敵戦やストーリーコンテンツのリスト、お勧めバッジなどを掲載したコーナーです。
期間限定のない普通のRPGですので、初心者でも安心して続けていけるゲームとなっています。
もっとも重要なグラスタについては、場所別に網羅した表があります。

個人サイトのホスティングとコンテンツ作成

個人でウェブサイトを作るにはどうすればいいか。
HTML・CSS・JavaScriptの書き方はもちろん、無料かつ広告なしでホームページを作る方法を掲載したコーナーです。
Webデザインやレイアウトについても書いてあります。

魚釣りなどアウトドアのエリア

ゲームとパソコンだけじゃなく、アウトドアも趣味なんです。
このコーナーでは魚釣りの記録とか、魚料理のレシピ、はたまたサイクリングなどなど。
アウトドアに関連するコンテンツが詰め込まれています。