0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Sortable.jsをつかったドラッグアンドドロップの方法

Posted at

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Menu Switcher with Sortable.js</title>
<style>
  body {
    font-family: sans-serif;
    background: #f8f9fa;
    padding: 40px;
  }

  .c-menu-switcher {
    display: flex;
    align-items: flex-start;
    gap: 20px;
  }

  .c-menu-switcher__menu {
    width: 220px;
    min-height: 200px;
    background: #fff;
    border: 2px solid #ccc;
    border-radius: 12px;
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
  }

  .c-menu-switcher__item {
    padding: 8px 10px;
    background: #f0f0f0;
    border-radius: 8px;
    cursor: grab;
    transition: 0.2s;
  }

  .c-menu-switcher__item.is-selected {
    background: #007bff;
    color: #fff;
  }

  .c-menu-switcher__buttons {
    display: flex;
    flex-direction: column;
    gap: 10px;
    justify-content: center;
  }

  button {
    padding: 8px 12px;
    border: none;
    border-radius: 8px;
    background: #007bff;
    color: #fff;
    cursor: pointer;
  }

  button:hover {
    background: #0056b3;
  }

  /* Sortable.jsドラッグ中 */
  .sortable-ghost {
    opacity: 0.4;
  }

  .is-dragging {
    background: #cce5ff !important;
  }

</style>
</head>
<body>

<div class="c-menu-switcher js-menu-switcher">
  <div class="c-menu-switcher__menu c-menu-switcher__menu--visible js-visible">
    <div class="c-menu-switcher__item" data-id="home">ホーム</div>
    <div class="c-menu-switcher__item" data-id="news">ニュース</div>
    <div class="c-menu-switcher__item" data-id="contact">お問い合わせ</div>
  </div>

  <div class="c-menu-switcher__buttons">
    <button class="js-add-btn">→ 追加</button>
    <button class="js-remove-btn">← 削除</button>
  </div>

  <div class="c-menu-switcher__menu c-menu-switcher__menu--hidden js-hidden">
    <div class="c-menu-switcher__item" data-id="about">会社情報</div>
    <div class="c-menu-switcher__item" data-id="service">サービス</div>
    <div class="c-menu-switcher__item" data-id="blog">ブログ</div>
  </div>
</div>

<!-- Sortable.js CDN -->
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>

<script>
document.addEventListener('DOMContentLoaded', () => {

  function moveItem(item, targetMenu) {
    if (!item || !targetMenu) return;
    targetMenu.appendChild(item);
    item.classList.remove('is-selected');
  }

  function initSelection(switcher) {
    switcher.addEventListener('click', (e) => {
      if (!e.target.classList.contains('c-menu-switcher__item')) return;
      const menu = e.target.closest('.c-menu-switcher__menu');
      menu.querySelectorAll('.c-menu-switcher__item').forEach(i => i.classList.remove('is-selected'));
      e.target.classList.add('is-selected');
    });
  }

  function sortableOptionsFactory(groupName) {
    return {
      group: {
        name: groupName,
        pull: true,
        put: true
      },
      animation: 150,
      ghostClass: 'sortable-ghost',
      chosenClass: 'is-dragging',
      onEnd: (evt) => {
        console.log('Moved:', evt.item.dataset.id, '', evt.to.className);
      }
    };
  }

  const switchers = document.querySelectorAll('.js-menu-switcher');
  switchers.forEach((switcher, index) => {
    initSelection(switcher);

    const visibleMenu = switcher.querySelector('.js-visible');
    const hiddenMenu = switcher.querySelector('.js-hidden');
    const addBtn = switcher.querySelector('.js-add-btn');
    const removeBtn = switcher.querySelector('.js-remove-btn');

    // Sortable初期化(上下ドラッグ+左右移動OK)
    const opts = sortableOptionsFactory('menuGroup-' + index);
    new Sortable(visibleMenu, opts);
    new Sortable(hiddenMenu, opts);

    // ボタンでの移動
    addBtn.addEventListener('click', () => {
      const selected = hiddenMenu.querySelector('.is-selected');
      if (selected) moveItem(selected, visibleMenu);
    });

    removeBtn.addEventListener('click', () => {
      const selected = visibleMenu.querySelector('.is-selected');
      if (selected) moveItem(selected, hiddenMenu);
    });
  });

});
</script>

</body>
</html>

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?