ブログでよく見る「もっと見る」で記事を全展開するオブジェクトを、JavaScriptで作ります。
これは、大手メディアで比較的よく見かけるUIです。
サンプルも交え解説していくので、是非参考にしてみてください。
.previousElementSibling
JavaScriptの previousElementSibling
は、指定した要素の1つ前の要素を取得するプロパティです。
例えば以下のような li
タグで要素を取得した場合、以下の通りです。
<ul>
<li>1個目</li>
<li id="targetElement">2個目</li>
<li>3個目</li>
</ul>
<script>
const element = document.getElementById( "targetElement" ) ; // 2個目のtargetElementを取得
const previousElementSibling = element.previousElementSibling ; // 2個目の前の1個目を指定
</script>
親要素じゃなく、並列の兄弟要素で取得します。
また、次の要素を取得する場合は nextElementSibling
プロパティを使います。
ボタンクリックでコンテンツが展開するサンプル
早速サンプルです。下部の「もっと見る」ボタンをクリックすると、非表示になっていた長い文章が全て展開され、「もっと見る」ボタンが消えます。
山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。とかくに人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟った時、詩が生れて、画が出来る。山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。とかくに人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟った時、詩が生れて、画が出来る。山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。
山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。とかくに人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟った時、詩が生れて、画が出来る。山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。とかくに人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟った時、詩が生れて、画が出来る。山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。とかくに人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟った時、詩が生れて、画が出来る。
文字量の多いブログで見かけるUIです。
サンプルのコード
コードはHTML・JavaScript・CSSの3種です。順に解説していきます。
HTML
HTMLは、まず「readMoreWrapper」のclass名で親要素を作ります。
そして、「readMore content-hidden」のclass名の div
タグでボタンクリックで展開を行うコンテナを作り、その兄弟要素で「read-more-container」の div
タグでもっと見るボタンを作ります。
<div class="readMoreWrapper">
<div class="readMore content-hidden">
<p>山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。とかくに人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟った時、詩が生れて、画が出来る。山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。とかくに人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟った時、詩が生れて、画が出来る。山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。</p>
<p>山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。とかくに人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟った時、詩が生れて、画が出来る。山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。とかくに人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟った時、詩が生れて、画が出来る。山路を登りながら、こう考えた。智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。とかくに人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟った時、詩が生れて、画が出来る。</p>
</div>
<div class="read-more-container">
<button class="open-read-more" id="one">もっと見る</button>
</div>
</div>
JavaScript
JavaScriptは、主に3種の .addEventListener()
イベントで処理を行なっていきます。
window.addEventListener('DOMContentLoaded', (event) => {
const readMore = document.querySelectorAll('.open-read-more')
if (readMore) {
readMore.forEach(read => new ReadMore(read))
}
});
class ReadMore {
constructor(element) {
this.element = element;
this.parentSibling = element.parentElement.previousElementSibling;
this.windowResize();
window.addEventListener('resize', this.windowResize.bind(this));
window.addEventListener('onorientationchange', this.windowResize.bind(this));
this.openReadMore();
}
openReadMore() {
this.element.addEventListener('click', () => {
this.parentSibling.style.maxHeight = `${this.parentSibling.scrollHeight}px`;
this.parentSibling.classList.remove('content-hidden');
this.element.style.display = "none";
})
}
windowResize() {
if (!this.parentSibling.classList.contains('content-hidden')) {
this.parentSibling.style.maxHeight = `${this.parentSibling.scrollHeight}px`;
this.parentSibling.style.transition = "none";
}
}
}
イベントは以下の通りです。
- DOMContentLoaded … 最初の HTML 文書の読み込みと解析が完了した時。
- resize … ブラウザのウィンドウサイズが変更された時。
- click … クリックされた時。
それぞれのイベントで役割が異なるので、カスタマイズする場合はそれぞれのイベントでいじるようにしましょう。
CSS
CSSは、クリックでclassの書き換えて表示切り替えを行わないので、コード量は少なめです。
.readMoreWrapper {
display: block;
position: relative;
}
.content-hidden::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 100px;
background: linear-gradient( to bottom,
rgba(255, 255, 255, 0.3) 0%,
rgb(250, 250, 250) 100% );
pointer-events: none;
}
.readMore {
transition: max-height 0.4s ease-out;
position: relative;
overflow: hidden;
max-height: 180px;
}
.read-more-container {
text-align: center;
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
}
.readMore p:last-child {
margin-bottom: 0;
}
展開前のサイズをいじる場合は readMore
のclassをいじりましょう。