記憶に残ったことを忘れないために色々メモとしてのこしていきます

画面描画メソッドの実行について

世の中、SPAベースの開発が完全に主流になりつつあるように謳われているが、レガシーページの対応などで相当な数のページがVanilla JSをつかってゴリゴリDOM操作をしているのではと思っている。その際、どうやって描画処理を実行するかについてとても簡単ではあるが、コードの可読性をあげる個人的なTipsを紹介したいと思う。(←もっとベターな方法があれば知りたいです)

例えば、ポップアップを表示/非表示を切り替える処理を考えてみる(簡単のため display プロパティで制御)。
下記では .popup-open-button をクリックすると、ポップアップが開き、 .popup-close-button をクリックすると閉じる処理を想定している。

const popup = querySelector('.popup')
const openButton = querySelector('.popup-open-button')
const closeButton = querySelector('.popup-close-button')

openButton.addEventListener('click', () => {
  popup.style.display = 'block'
})

closeButton.addEventListener('click', () => {
  popup.style.display = 'none'
})


まあこんな感じでかける。シンプルな実装であればこんな感じでいいと思うが、実際は表示する条件が追加されることがほとんどだ。そのとき、イベントハンドラー内で if 文を追加してしまうと、あっというまに可読性・メンテナンス性が失われてしまう。

openButton.addEventListener('click', () => {
  if (条件A) {
    popup.style.display = 'block'
  } else {
    popup.style.display = 'none'
  }
})


そこで使える考え方が、処理の分解だ (「責務の分解」とか言われてますね。小難しく聞こえるので、個人的にはあまり好きではない)。つまり表示・非表示の状態は別のオブジェクトで管理し、画面描画についても別のメソッドに切り替えてあげることで、読みやすいコードにすることができる。

const state = {
  isOpen: false,
}

function render (state) {
  const { isOpen } = state;
  if (isOpen) {
    popup.style.display = 'block'
  } else {
    popup.style.display = 'none'
  }
}
  
openButton.addEventListener('click', () => {
  state.isOpen = true;
  render(state)
})

もっとベターな方法があるかもしれないが、簡易的な実装であれば上記のような分解で、処理の管理もしやすくなる。