前提
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 };
以上、お力添えよろしくお願いいたします。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/08/20 13:01 編集