質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

2270閲覧

ディレクトリ内の他のファイル名を取得して動的に追加したい

zuny

総合スコア11

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/08/20 07:44

編集2021/08/21 01:19

前提

PHPを使えない、CMSも使えない案件で、HTML,CSS,JSのみでウェブサイトを構築しています。

ブログ記事一つ一つにhtmlのページがあるのではなく、ブログページ1ページにリストタグで記事がずらりと並んでいる状態です。(一つの記事が数行しかないため。)

最初はpost.htmlというファイルを作り、そこにliタグを並べ、ブログページのulタグの中にXMLHttpRequestでinnerHTMLを埋め込む。という形にしていました。(これは、クライアントが記事更新をしやすくするために、記事部分のみ切り分けた方がいいと思ったからです。)

blog.html //ブログのトップページ post.html //内容をblog.htmlに出力

また、selectタグを記事上部に追加して、optionで年を選べるようにしました。liタグの中にtimeタグで年月日を記述しているので、年を抜き取ってliタグにそれぞれの年のクラスをつけ、その年をjsで取得し配列にし、optionに追加。そしてselectのプルダウンで選んだ年以外はdisplay:none;になり、選んだ年のみ表示されるようにしていました。

イメージ説明

しかし、記事が増えた際に全ての記事が一つのファイルにあるのはデータも大きくなるしあまり良くないですよね...。(画像を入れる記事もあるので...。)

実現したいこと

そこで、/post/というディレクトリに「2020.html」「2021.html」と年毎に分けたファイルを用意し、選んだ年を出力するという方式に変えました。この出力自体は問題がないのですが、selectタグにoptionを追加するというところで躓きました。

blog.html //ブログのトップページ post L 2019.html L 2020.html L 2021.html

具体的な実現したいこととしてはディレクトリの/post/にあるhtmlファイルのタイトルを取得し、それぞれoptionタグに追加することです。optionタグを手打ちではなく、ファイル名から動的に取得して入れるということがしたいです。(新しい年になった場合に、記事更新(ファイルを追加)をするだけでoptionに新しい年がが追加されている状態)

可能な限り調べてみましたが、私のリサーチ力では回答にたどり着けなかったので質問をさせていただきました。言語はHTML,CSS,JSのみ使用可能です。可能であれば方法を、不可能であれば不可能または代替手段をお教えいただければ幸いです。

下記は前提段階での動作しているソースコードです。(不要な部分は省いています)

前提段階のソースコード(動作しているコードです。)

【blog.html】

html

1<select name="year" class="js-select"> 2          <option value="latest">年を選択</option> 3</select> 4<ul id="test"></ul>

【post.html】

html

1<li> 2 <time>2020/03/37</time> 3 <h2>タイトル</h2> 4 <p>本文</p> 5</li>

js

1const $select = document.querySelector('.js-select'); 2 const v = $select.options[$select.selectedIndex].value; 3 const x = new XMLHttpRequest(); 4 x.open('GET', '/post.html');// post.htmlファイルから読み取り 5 x.responseType = 'document'; 6 x.send(); 7 x.onreadystatechange = () => { 8 if(x.readyState === 4 && x.status === 200) { 9 // 記事部分の読み込み 10 document.querySelector('#test').innerHTML = x.response.documentElement.innerHTML; 11 12 // 年ごとのクラスを付与 13 const $li = document.querySelector('#test').querySelectorAll('li'); 14 $li.forEach( e => e.classList.add(e.querySelector('time').innerText.slice(0, 4))); 15 16 // selectに年を追加 17 const yearArray = Array.from(new Set(Array.prototype.slice.call(document.querySelectorAll('time')).map( e => e.innerText.slice(0, 4)))); 18 let y = 0; 19 while(y < yearArray.length){ 20 const o = document.createElement('option'); 21 o.text = yearArray[y]; 22 o.value = yearArray[y]; 23 $select.appendChild(o); 24 y++; 25 } 26 // selectで選択したものだけ出力 27 $select.addEventListener('change', () => { 28 const v = $select.options[$select.selectedIndex].value; 29 $li.forEach( e => { 30 if(e.classList.contains(v) || v === 'none'){ 31 e.style.display = 'block'; 32 } else { 33 e.style.display = 'none'; 34 } 35 }); 36 }); 37 } 38 };

以上、お力添えよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

クライアントのみでいちおう実現可能です。記事の画像などはロード不要になるので、全記事が1ファイルに入るよりトラフィックは減るかもしれません。

例:
一番古い記事の年を例えば let y = 2018; として、/post/${y}.html を XHR で取得してみる。status200 なら <option>y をたして、++y してループ。status200 以外ならループ終了。

もちろん効率が良いとは言えないので、こういうのはサーバサイドで処理するのが普通です。

投稿2021/08/20 08:13

編集2021/08/20 08:20
int32_t

総合スコア21020

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zuny

2021/08/20 13:01 編集

ご回答ありがとうございます。 教えていただいた例を参考にして、optionの動的追加が実現できました...!!(コンソールログのエラーメッセージで最後のループの際のhtmlの404のエラーメッセージが出てしまうのはどうしようもないですよね...。) 私の力量的にも環境的にも、今回はこれしか方法がないと思うので、この方法で行きたいと思います。大変参考になる回答を迅速にしていただきありがとうございました!
guest

0

サーバーサイドでプログラムを動かせない場合は、無理と思った方が良いですが、
サーバー側の環境と、あなたのセキュリティー方針によっては、やってやれないことは無いです。

ディレクトリに、index.htmlindex.php等が無い場合に、ディレクトリ内のファイル一覧が見える様に設定できます。例えば、こんなページです Index of /pub

XMLHttpRequestでそのディレクトリにアクセスすれば必要な情報は得られるので、あとは文字列処理だけです。

Apacheなら.htaccessOptions +Indexesです。
普通は、ファイル一覧を公開することはセキュリティー的な意味で避けるので、禁止してあるはずですが、公開して良いのならこの方法で出来ます。なお、サーバーの設定で、Options +Indexes自体が禁止されているかも知れません。

投稿2021/08/20 11:01

otn

総合スコア84808

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2021/08/20 11:04

まあ、「JavaScriptでサーバーのファイル一覧を見たい」=「JavaScriptを解析した人にはサーバーのファイル一覧が見えちゃってもかまわない」なので、あなたのポリシー的には問題なしですかね。
zuny

2021/08/20 12:57

ご回答ありがとうございます。なぜJSからアクセスができないのか、理由がよくわかりました。不勉強で申し訳有りません。
guest

0

サーバサイドに仕掛けをしない限り不可能です。「ファイルリスト」を取得する手段そのものが存在しません。

投稿2021/08/20 07:59

maisumakun

総合スコア145208

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zuny

2021/08/20 08:07

やはりJSではできないのですね。ご回答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問