kintoneアプリ内のカテゴリ部分のスクロール制御について

kintone初心者です。

kintoneアプリにて社内向けのFAQアプリを作成しています。
レコード一覧画面においてカテゴリーを有効にした場合、カテゴリーとレコード一覧まとめて、スクロールされるようになっておりますが、このスクロールをそれぞれ独立させたいです。
造りのイメージとしてはkintoneのFAQサイトが理想です。
標準機能では実現が難しいと思いますが、カスタマイズなどでなんとかこのような機能は実現できますでしょうか。

※この回答には非推奨のDOM操作を含むことを先にお伝えしておきます。


カテゴリーのスクロール、全然気にしたことはなかったんですが、確かに kintone を使い始めたころはスクロールしづらいなって思った記憶がありました。慣れって怖いものですね。

面白そうとおもって試しにやってみたら、意外と形になったので、共有します。

CSS

@charset "UTF-8";

.view-category-container-gaia {
  position: sticky;
  top: 48px;
  overflow-y: auto;
}

JavaScript

(() => {
  'use strict';

  let initialized = false;
  
  kintone.events.on('app.record.index.show', (event) => {
    if (!initialized) {
      setScrollBehavior();
      initialized = true;
    }
  });

  /**
   * スクロール時の挙動を登録します
   */
  async function setScrollBehavior() {
    
    // カテゴリー要素を取得
    const element = await getCategoryElement();
    if (element) {
      
      // スクロール時イベントに登録
      document.addEventListener('scroll', () => fitCategoryElement(element));
      
      // 最初の1回だけ手動実行
      fitCategoryElement(element);
    }
  }

  /**
   * カテゴリー要素を取得します (最大10回リトライ)
   */
  async function getCategoryElement() {
    let cnt = 10;
    while (cnt-- > 0) {
      const element = document.querySelector('.view-category-container-gaia');
      if (element) return element;
      await new Promise(resolve => setTimeout(resolve, 100));
    };
  }

  /**
   * カテゴリー要素を画面の高さにフィットさせます
   * @param {HTMLElement} element カテゴリー要素
   */
  function fitCategoryElement(element) {

    // 要素の表示領域を取得
    const elementRect = element.getBoundingClientRect();
    const parentRect = element.parentElement.getBoundingClientRect();

    // 目的の表示位置を計算
    // top: 現在の表示領域のtop (画面上部の黒いバー48pxより上に行かないように)
    // bottom: ウィンドウの最下端 (親要素の表示領域のbottomより下に行かないように)
    const targetTop = Math.max(elementRect.top, 48);
    const targetBottom = Math.min(window.innerHeight, parentRect.bottom);

    // 高さを設定
    element.style.maxHeight = `${targetBottom - targetTop}px`;
  }
})();

仕組みとしては position: sticky でスクロールしても画面上部に粘着するようにして、高さを画面内に収まるくらいに設定してあげるような感じです。

シンプルにやるのであれば、 CSS 側で max-height100vh とか calc(100vh - 48px) を指定してあげればいいのですが、一番下までスクロールした時とかの挙動がちょっと変になってしまうので、解決しようとしたら JavaScript で再計算する方法しか思いつきませんでした。

やりたいこと自体は fitCategoryElement 関数と CSS で全部やっていて、それ以外のコードはイベント登録などです。

そこまでちゃんと確認したわけではないので変な挙動が起こるかもしれませんが、ご参考になれば。

2 Likes

住田様

ご回答いただきありがとうございます。

ご共有頂いたコードを適用したところ、まさにイメージ通りのレイアウトが完成いたしました。
質問前に数時間試行錯誤していたのがウソのようです…

この度はコードのご提案、仕組みの解説までご丁寧にいただき、
ありがとうございました!

1 Like

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。