網頁前端拖曳套件 | 元素排序 移動 拖放 | SortableJS | 3分鐘Move

今天來介紹網頁前端拖曳套件,身為一個前端工程師,百思不得其解如何讓使用者任意的移動我們寫死的HTML,該怎麼做到從這邊跑到另一邊三仙歸洞? SortableJS 這個JS拖曳套件讓我們任意排序元素,使用拖拉的方式讓網站更有互動性,一起來試試看這方便的魔法套件吧!!

SortableJS 官網(有範例參考)

SortableJS GitHub(程式原始碼)

Let's Drag and Drop

Place item in the right color

Yellow
Banana
Tomato
Chili
Red
Apple
Sun Flower
Pineapple

前端拖曳套件-SortableJS

Item 1
Item 2
Item 3
Item 4
Item 5

步驟說明

  1. 引入套件Javascript
    – JavaScript 放置於要開發的 <script> 之前
    前端拖曳套件
  2. 加入HTML、Javascript
    – 創建一個div排序區塊
    – 在JavaScript區塊加入Sortable功能實例
    前端拖曳套件使用
  3. 附上程式碼(下方有程式碼說明)
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        .item-box {
            border: 1px solid #e3e3e3;
            padding: 1rem;
            width: 300px;
            cursor: pointer;
        }
    </style>
</head>

<body>
    <div id="sortable1">
        <div class="item-box">Item 1</div>
        <div class="item-box">Item 2</div>
        <div class="item-box">Item 3</div>
        <div class="item-box">Item 4</div>
        <div class="item-box">Item 5</div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>

    <script>
        const sortable1El = document.getElementById('sortable1')
        const sortable1 = Sortable.create(sortable1El, {
            animation: 150
        })
    </script>
</body>

程式碼說明

第22行: 引入SortableJS套件來源(必須在JS使用之前)
第25行: document.getElementById 取得我們要套用HTML元素ID
第26行: Sortable.create 創建一個可排序拖曳的物件
第27行: animation: 拖曳套件動畫時間(ms)

雙區塊拖曳

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10


– 建立兩個不同id的標籤區塊(下方JS程式碼第3行、第10行)
– 都使用 group 屬性並取相同名字(ex: shared、group1…)
pull: “clone” 表示移動HTML標籤至另一區塊不會被移除
(範例中: 從左移動到右邊會移除,但從右邊移動到左邊元素依舊存在)

.item-box {
    border: 1px solid #e3e3e3;
    padding: 1rem;
    width: 300px;
    cursor: pointer;
}
.bg-gray {
    background-color: #f3f3f3;
}
.sort-box {
    display: flex;
}
<body>
    <div class="sort-box">
        <div id="sortable1">
            <div class="item-box">Item 1</div>
            <div class="item-box">Item 2</div>
            <div class="item-box">Item 3</div>
            <div class="item-box">Item 4</div>
            <div class="item-box">Item 5</div>
        </div>
        <div id="sortable2">
            <div class="item-box bg-gray">Item 6</div>
            <div class="item-box bg-gray">Item 7</div>
            <div class="item-box bg-gray">Item 8</div>
            <div class="item-box bg-gray">Item 9</div>
            <div class="item-box bg-gray">Item 10</div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>

    <script>
        const sortable1El = document.getElementById("sortable1")
        const sortable1 = Sortable.create(sortable1El, {
            group: "shared", // 本章節新增 共享區塊
            animation: 150
        })
        const sortable2El = document.getElementById("sortable2")
        const sortable2 = Sortable.create(sortable2El, {
            group: { // 本章節新增
                name: 'shared', // 共享區塊
                pull: 'clone' // 移動不移除
            },
            animation: 150
        })
    </script>
</body>

限制拖移

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10


– 左側區塊新增 sort: false 屬性,表示不能排序此區塊(但仍有雙區塊拖曳)
– 右側區塊新增 put: false 屬性,表示不能被加入標籤
(左移動至右會失敗)

<script>
    const sortable1El = document.getElementById("sortable1")
    const sortable1 = Sortable.create(sortable1El, {
        group: "shared",
        animation: 150,
        sort: false // 本章節新增 不能排序此區塊
    })
    const sortable2El = document.getElementById("sortable2")
    const sortable2 = Sortable.create(sortable2El, {
        group: {
            name: 'shared',
            pull: 'clone',
            put: false // 本章節新增 不能被加入標籤
        },
        animation: 150
    })
</script>

拖曳區塊指定

Drag
Item 1
Lock
Item 2
Drag
Item 3


– 加入 handle: “.handle” 表示只能在.handle class底下包含的元素才能拖曳
– 加入 filter: “.lock” 表示有.lock class的元素不能被拖曳

.handle, .lock {
    cursor: pointer !important;
    padding: 0 0.5rem;
    background-color: #bbf09e;
    border-radius: 5px;
    margin-right: 5px;
    color: #fff;
}
.lock {
    background-color: #f0a29e !important;
    cursor: no-drop !important;
}
<body>
    <div id="sortable1">
        <div class="item-box">
            <div class="handle">Drag</div>
            Item 1
        </div>
        <div class="item-box">
            <!-- 有 lock class -->
            <div class="handle lock">Lock</div>
            Item 2
        </div>
        <div class="item-box">
            <div class="handle">Drag</div>
            Item 3
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>

    <script>
        const sortable1El = document.getElementById("sortable1")
        const sortable1 = Sortable.create(sortable1El, {
            handle: ".handle", // 本章節新增 限制能拖曳的class區塊
            filter: ".lock", // 本章節新增 有此class表示不能被拖曳
            animation: 150
        })
    </script>
</body>

多選拖曳

Item 1
Item 2
Item 3
Item 4
Item 5


– 加入 multiDrag 可以多選標籤
– 加入 selectedClass 來更改多選時的css特效
– 加入 fallbackTolerance 讓手機版也能多選

.sortable-selected {
    background-color: #e3e3e3;
    border: 1px solid #000;
}
<script>
    const sortable1El = document.getElementById('sortable1')
    const sortable1 = Sortable.create(sortable1El, {
        multiDrag: true, // 可以多選
        selectedClass: "sortable-selected", // 多選時的class
        fallbackTolerance: 3, // 在手機版上可以多選
        animation: 150
    })
</script>

移動預視

Item 1
Item 2
Item 3
Item 4
Item 5


– 加入 swap 屬性能夠預視要移動至的區塊
– 加入 swapClass 來更改預視時的css特效

.highlight {
    background-color: yellow;
}
<script>
    const sortable1El = document.getElementById("sortable1")
    const sortable1 = Sortable.create(sortable1El, {
        swap: true, // 加入預視
        swapClass: "highlight", // 預視時的css效果
        animation: 150
    })
</script>

總結

SortableJS簡單好玩的前端拖曳套件,幫你處理邏輯與動畫,加入一些簡單的屬性來實現我們的HTML拖曳排序,如果你喜歡就馬上加入到自己的專案內吧!!大家可以留言給我,或是任何操作有疑問都可以讓我知道,我會盡量在一週內回覆你留言與透過email回覆給你,祝各位開發順利。

Related Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *