📝

Slack のナビゲーションバーを非表示にする Chrome 拡張機能を作ってみた

に公開

Web 版の Slack で左側に表示されているナビゲーションバーを非表示にしてみました。

1. 拡張機能のフォルダとファイル作成

ローカル PC 内に任意のフォルダを作成し、以下のファイルを作成します。

  • manifest.json
  • content.js

今回は以下のようなフォルダ構成にしました。

slack-nav-hider/
├── manifest.json
├── content.js

2. ファイルの編集

Slack Tweaks · GitHub
スクリプトの処理は上記 GitHub を参考にしました。

まずは manifest.json に以下の内容を張り付けて保存します。

manifest.json
{
  "manifest_version": 3,
  "name": "Slack Nav Hider",
  "version": "0.1.0",
  "description": "Hide navigation bars in Slack web app.",
  "content_scripts": [
    {
      "matches": ["https://app.slack.com/*", "https://*.slack.com/*"],
      "js": ["content.js"],
      "run_at": "document_idle"
    }
  ]
}

次に content.js に以下の内容を張り付けて保存します。

content.js
// content.js
(function () {
  "use strict";

  // 実際にナビゲーションを非表示にする処理
  function tryHideNav() {
    try {
      const helpBtn = document.querySelector('[data-qa="top-nav-help-button"]');
      const userBtn = document.querySelector('[data-qa="user-button"]');

      // 必要な要素が見つからなければ false を返して再試行させる
      if (!helpBtn || !userBtn) return false;

      // あなたがコンソールでやっていた DOM 操作(要素移動)
      const afterNode =
        helpBtn.parentNode &&
        helpBtn.parentNode.parentNode &&
        helpBtn.parentNode.parentNode.parentNode;
      const userContainer = userBtn.parentNode && userBtn.parentNode.parentNode;
      if (afterNode && userContainer) {
        try {
          afterNode.insertAdjacentElement("afterend", userContainer);
        } catch (e) {
          // 既に移動済みの可能性は無視
        }
      }

      // 非表示にする要素群(見つかれば display:none にする)
      const tabRail = document.querySelector(".p-tab_rail");
      if (tabRail) tabRail.style.display = "none";

      const controlStrip = document.querySelector(".p-control_strip");
      if (controlStrip) controlStrip.style.display = "none";

      const workspace = document.querySelector(
        ".p-ia4_client .p-client_workspace--including_tab_rail"
      );
      if (workspace) {
        try {
          workspace.style.gridTemplateAreas =
            "p-client-workspace p-client-workspace";
          // className を上書きすると将来の Slack 側クラス付与で想定外動作することがあるため上書きは慎重に
          workspace.classList.add("p-theme_background"); // className = ... の代わりに追加に変更
        } catch (e) {
          // 無視
        }
      }

      return true;
    } catch (err) {
      // 予期せぬエラーでも落とさない
      return false;
    }
  }

  // 初回実行(DOM がまだ完全でない場合に備えて)
  if (
    document.readyState === "complete" ||
    document.readyState === "interactive"
  ) {
    tryHideNav();
  } else {
    window.addEventListener("DOMContentLoaded", tryHideNav);
  }

  // ページの DOM 変化(遅延ロードや SPA の切り替え)を監視して成功したら監視停止
  const observer = new MutationObserver((mutations, obs) => {
    if (tryHideNav()) {
      // 成功したら監視解除(ただし将来のナビ復活に備えたい場合は解除しない選択肢もあり)
      obs.disconnect();
    }
  });

  observer.observe(document.documentElement || document.body, {
    childList: true,
    subtree: true,
  });

  // single-page app 対応:history.pushState / replaceState をラップして URL 変更時に再実行
  (function () {
    const _push = history.pushState;
    history.pushState = function () {
      const ret = _push.apply(this, arguments);
      setTimeout(tryHideNav, 200); // 少し遅らせて実行
      return ret;
    };
    const _replace = history.replaceState;
    history.replaceState = function () {
      const ret = _replace.apply(this, arguments);
      setTimeout(tryHideNav, 200);
      return ret;
    };
    window.addEventListener("popstate", () => setTimeout(tryHideNav, 200));
  })();

  // 安全のため、定期的に(最大回数)リトライするフォールバック
  (function () {
    let attempts = 0;
    const maxAttempts = 30; // 30 回(合計約30秒程度)
    const interval = setInterval(() => {
      attempts++;
      if (tryHideNav() || attempts >= maxAttempts) clearInterval(interval);
    }, 1000);
  })();
})();

3. Chrome で読み込む

手順 1,2 完了後、Chrome の拡張機能のページから手順 1 で作成したフォルダを読み込みます。

4. 動作確認

手順 3 完了後、Web 版の Slack を開き、ナビゲーションバーが非表示になれば OK です。
すでに Slack を開いている場合はリロード後にナビゲーションバーが非表示になれば OK です。

まとめ

今回は Slack のナビゲーションバーを非表示にする Chrome 拡張機能を作ってみました。
どなたかの参考になれば幸いです。

参考資料

Discussion