Help us understand the problem. What is going on with this article?

メニューが横幅に収まらない時に右上に収納されるやつ

More than 1 year has passed since last update.

あまりサンプルが見つからなかったのでやってみた。
こういう動きを何て言うのか分からないので、自分が見つけられなかっただけの可能性は否めないです・・・。

デモ

See the Pen navbar with menu storage by Yoshiaki Itakura (@negibouze) on CodePen.

ちょっと解説

せっかくなので、Intersection Observerを使ってみました。
ポイントはroot#menuにするところくらいです。

const setIntersectionObserver = () => {
  const observerOptions = {
    root: document.querySelector("#menu"), // menuをroot要素にする
    rootMargin: "0px",
    threshold: [0.8]
  };

  const items = document.querySelectorAll(".menu-item");
  observer = new IntersectionObserver(
      intersectionCallback,
      observerOptions
    );
  // menu-itemを監視対象にする
  for (const item of items) {
    observer.observe(item);
  }
}

entry.isIntersectingで処理を分岐します。
true: 見えるようになった
false: 見えなくなった

const intersectionCallback = (entries) => {
  entries.forEach(entry => {
    const target = entry.target;
    const storage = document.querySelector(".storage");
    if (entry.isIntersecting) {
      // navbarのメニューを表示する
      target.classList.remove("invisible");
      const len = overflowMenuItems.length;
      if (1 <= len) {
        if (len === 1) {
          // 最後の要素が表示された時は、more(縦の「・・・」)を非表示にする
          storage.classList.add("hide");      
        }
        // 収納していたメニューの先頭を削除する
        overflowMenuItems.shift();
      }
    } else {
      // あふれメニューの末尾に要素のクローンを追加する
      overflowMenuItems.unshift(target.cloneNode(true));
      // navbarのメニューを非表示にする
      target.classList.add("invisible");
      // more(縦の「・・・」)を表示する
      storage.classList.remove("hide");
    }
  });
  sortOverflowItems();
  createOverflowMenu();
}

並び順を保証するために、data属性のorderでsortします。
※これをやらないと、初回表示時に横幅が足りない時に並び順が保証されない

const sortOverflowItems = () => {
  overflowMenuItems.sort((a, b) => {
    return a.dataset.order < b.dataset.order ? -1 : 1;
  })
}

#overflowMenuの子要素にあふれた分のメニューを追加します。
差分更新にした方が良いと思いますが、ひとまず毎回、既存の子要素を全削除してから、再度追加しています。

const createOverflowMenu = () => {
  const menu = document.querySelector("#overflowMenu");
  // 一回全部消す
  while (menu.firstChild) {
    menu.removeChild(menu.firstChild);
  }
  for (const item of overflowMenuItems) {
    menu.appendChild(item);
  }
}

おまけ: ドラッグで横幅を変えるやつ(動作確認用)

/* 動作確認用 */
const wrapper = document.querySelector(".wrapper");

const addResizeEvent = () => {
  const rightEdge = document.querySelector(".right-edge");

  rightEdge.addEventListener("mousedown", initResize, false);
}

const initResize = (e) => {
  window.addEventListener("mousemove", Resize, false);
  window.addEventListener("mouseup", stopResize, false);
}

const Resize = (e) => {
  wrapper.style.width = `${e.clientX - wrapper.offsetLeft}px`;
}

const stopResize = (e) => {
  window.removeEventListener("mousemove", Resize, false);
  window.removeEventListener("mouseup", stopResize, false);
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした