イベントが発生した時、その兄弟要素を操作する方法


概要

jQueryを使用せずに実装することを目指す。
同じ構造をした要素が複数存在する際に、その中でイベントが発生した兄弟要素だけを操作したい場合の実装方法である。

実装例

クリックしたらその兄弟要素にあたる画像を小さくするボタンを実装。今回は同じ構造の要素を4つ用意。

HTMLとcss

参考程度に掲載

HTML
<ul class="item-list">
    <li class="item-list__item">
        <img src="images/1.jpeg" alt="img1" class="img-op">
        <button class="popup-btn btn">look</button>
    </li>
    <li class="item-list__item">
        <img src="images/2.jpeg" alt="img2" class="img-op">
        <button class="popup-btn btn">look</button>
    </li>
    <li class="item-list__item">
        <img src="images/3.jpeg" alt="img3" class="img-op">
        <button class="popup-btn btn">look</button>
    </li>
    <li class="item-list__item">
        <img src="images/4.jpeg" alt="img4" class="img-op">
        <button class="popup-btn btn">look</button>
    </li>
</ul>

SCSS
button {
    overflow : hidden;
    outline : none;
}
.text-center {
    text-align: center;
}
.img-pc {
    display:none;
}
.wrapper {
    box-sizing: border-box;
    padding: 0 20px;
}
.btn {
    display: block;
    border-radius: 2px;
    -webkit-appearance:none;
    appearance:none;
    padding:  8px 16px;
    font-size: 1.2rem;
    border:none;
    color: #fff;
    background-color: $main-color;
    font-family: 'Montserrat', sans-serif;
    outline: none;
    cursor: pointer;
}
.item-list {
    //パラメータ
    $marginLeft: 16px;

    //プロパティ
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 32px;
    margin-left: (-1 * $marginLeft);
    padding: 0 16px;

    &__item {
        display: block;
        margin-top: 32px;
        margin-left: $marginLeft;
        width: 200px;
    }
}
.img-op {
    width: 240px;
    height: 96px;
    display: block;
    border-radius: 8px;
    object-fit: cover;

    &.active {
        transform: scale(0.5);
    }
}
.img-input {
    display: none;
}

.popup-btn {
    display: block;
    margin: 16px auto;
}

Javascript

JavaScript
//popup-btnクラスの要素を全て取得
let popupBtns = Array.from(document.getElementsByClassName('popup-btn'));
popupBtns.forEach(function(popupBtn) {
//その中からクリックイベントが発生した要素を取得
  popupBtn.addEventListener('click', function() {
    //親要素に遡り、ymg-opクラスの要素を取得。activeクラスをtoggle。
    popupBtn.parentElement.getElementsByClassName('img-op')[0].classList.toggle('active');
  });
});

実装のヒント

考え方としては以下の通り。
jQueryだと簡単だけど、生jsだと結構面倒臭い。

  1. イベントが発生した要素を取得
  2. 1.で取得した要素の親要素を取得
  3. 2.の子要素を取得(1.の兄弟要素にあたる)
  4. 3.の要素を操作

という周りクドい手順を踏むことによって、やっとこさ兄弟要素を操作することができる。