拖拉元素~調整排序**~!
**網頁介面開發技巧是--拖拉元素調整排序**
**網頁上會顯示五個<span>方塊,
假設其排序有特定意義(例如: 出場順序,
決定先用皮卡丘之後再派妙蛙種子之類的),
使用者可用滑鼠或手指直接拖曳方塊--
--改變其排列順序,當某個方塊被拖到另一個方塊上,就對調兩個方塊的位置,
藉此自由調整所有方塊的排列順序**
****
****
**有興趣了解程式開發細節的*來看看程式裡用到的技巧: *
**
- 產生五個<span>方塊的部分,採用的--
- -- MVVM的做法。宣告了一個viewModel函數,
- 透過ko.observableArray()保存資料物件陣列,
- <div id="dvList" data-bind="foreach: items">
- 將資料物件陣列的每個元素對應成一個<span>
- ,用<span data-bind="text: name">可將屬性
- 當成<span>的內容。 viewModel函數中,
- var self = this;的做法可視為knockout.js中
- 的Best Practice **
- 為突顯knockout.js可即時反應資料變化的特性,
- 我刻意每隔0.5秒塞入一筆資料,讓我們可--
- --觀察到Player0到Player4逐一出現的過程。
- 而由於setTimeout塞入資料為非同步作業,
- 為了確保在全部完成後才執行下一步驟,
- 再次使用$.Deferred()的技巧處理同步化 ~!**
Drop功能。實測發現,用Kendo UI所開發的拖拉 -
-功能,不管在PC使用滑鼠操作或在行動裝置進行
手指觸控操作都很順暢,不需針對不同裝置特意
改寫,十分便捷。(但有些小眉角,例如: 有多個--
--放置目標時如何取得當時的放置目標,需要點--
--小技巧,細節可參見程式註解) ***
**至於方塊對調位置的動畫效果,則是--
--將<span>元素先轉成position: absolute,
再靠.animate({ left: 新座標 })搞定,對
-不過小菜一碟。
移動過程為了讓使用者有方塊是浮起來在空中-
-飛移的錯覺,
借用了CSS3的transform:
scale(1.1,1.1)讓<span>放大10%,此時早先介紹的HTML5/CSS3瀏覽器
支援速查工具派上用場,
查詢結果顯示要IE10, FF16才支援不加-ms-,
–moz-的寫法,Safari/Chrome則仍需要-webkit-,
所以乖乖加上-ms-, –moz-, –webkit-寫成三筆 **
**<span>對調順序的部分,用jQuery的.after()就
可以解決,但為了定址方便,我偷偷加放了
一個空白<span class='item-pos'>,
程式碼瞬間簡化許多**
**完整程式碼如下,已內含不少註解,
但坦白說,因涉及不少進階技巧,
程式碼並不好懂,希望註解夠清楚 ~!!
**
**
排版顯示純文字
<!DOCTYPE html>
<html>
<head>
<title>Drag to Swap Demo</title>
<script src="../Scripts/jquery-1.7.2.min.js"></script>
<script src="../Scripts/kendo/kendo.web.js"></script>
<script src="../Scripts/knockout-2.1.0.js"></script>
<link href="../Content/kendo/kendo.common.min.css"
rel="stylesheet" type="text/css" />
<link href="../Content/kendo/kendo.metro.min.css"
rel="stylesheet" type="text/css" />
<script>
//定義ViewModel類別
function viewModel() {
//將this另指派給self變數,之後以其代表View Model本體,
//避免與函數中的this所指的對象混淆
var self = this;
//定義一個集合存放資料
self.items = ko.observableArray();
//定義加入item的方法, 在items中加入具有name及score屬性的物件
self.addItem = function(name, score) {
self.items.push({ name: name, score: score });
};
}
$(function () {
//建立ViewModel
var vm = new viewModel();
//每隔0.5秒加一筆以觀察knockoutJs讓UI即時反應資料變化的效果
//使用jQuery.Deferred處理實現完成時機的同步
function job(i) {
var df = $.Deferred();
setTimeout(function () {
vm.addItem("Player" + i, i * 100);
df.resolve();
}, i * 500);
return df.promise();
}
//建立延遲0-4秒執行的加入item作業
var jobs = [];
for (var i = 0; i < 5; i++) {
jobs.push(job(i));
}
//等待所有job執行完畢,掛上Kendo UI拖拉功能
$.when.apply(null, jobs).then(function () {
var $items = $("span.item");
//加上拖曳特性,hint事件回傳拖曳過程顯示的元素
$items.kendoDraggable({
hint: function (e) {
return e.clone().addClass("drag-item");
}
})
.each(function () {
//由於kendoDropTarget事件中,
被放置對象this非亦無事件屬性可存取
//故使用Closure方式將元素存入$item供drop事件存取
var $item = $(this);
//加上放置目標特性才能接成為拖曳的目標
$item.kendoDropTarget({
//拖曳到目標元素上方及離開
時改變CSS,提供使用者可以放置的提示
dragenter: function (e)
{ $item.addClass("drop-item"); },
dragleave: function (e)
{ $item.removeClass("drop-item"); },
//在目標元素上方鬆開滑鼠或
手指離開觸控螢幕時觸發drop事件
drop: function (e) {
//透過以下方式取得拖曳元素及放置元素
var $drag = e.draggable.element;
var $drop = $item;
$drop.removeClass("drop-item");
//拖曳對象與放置目標相同時不處理
if ($drag.text() == $drop.text()) return;
//顯示位置交換動畫
//先將全部元素轉為絕對座標
$items.each(function () {
//先記下座標值,以.data()保存
var $elem = $(this);
$elem.data("pos", $elem.position());
})
.each(function () {
//維持座標位置,但換成絕對座標
var $elem = $(this);
var pos = $elem.data("pos");
$(this).css({
position: "absolute",
top: pos.top + "px",
left: pos.left + "px"
});
});
//$drag與$drop交換位置,使用animate
var dragLeft = $drag.data("pos").left + "px";
var dropLeft = $drop.data("pos").left + "px";
var $moving = $drag.add($drop);
$moving.addClass("move-item");
$drag.animate({ left: dropLeft }, 1000);
$drop.animate({ left:
dragLeft }, 1000, function () {
$moving.removeClass("move-item");
//交換位置
var $dragPos = $drag.prev(".item-pos");
$drop.prev(".item-pos").after($drag);
$dragPos.after($drop);
//改回相對座標
$items.css
({ position: "", left: "", top: "" });
});
}
});
});
});
//將ViewModel與UI結合
ko.applyBindings(vm);
});
</script>
<style>
html,body { font-size: 9pt; }
.item
{
font-family: Segoe UI; display: inline-block;
border: 1px solid gray;
margin-left: 5px; padding: 5px;
width: 80px; height: 25px;
background-color: #0099FF; color: white;
text-align: center;
}
.drag-item
{
opacity: 0.5;
background-color: #FF3300;
}
.move-item
{
z-index: 9;
-ms-transform: scale(1.1,1.1); /* IE 9 */
-webkit-transform: scale(1.1,1.1); /* Safari and Chrome */
-moz-transform: scale(1.1,1.1); /* Firefox */
}
#dvList { margin-top: 20px; }
.drop-item
{
background-color: Purple;
}
</style>
</head>
<body>
<div id="dvList" data-bind="foreach: items">
<span class='item-pos'></span>
<span class='item'>
<span class='item-name' data-bind="text: name"></span>
(<span class='item-score' data-bind="text: score"></span>)
</span>
</div>
</body>
</html>
**
****
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
沒有留言:
張貼留言
if you like make fds, wellcome you here~~anytime***
my free place for everyones who want the good software,
come & download them~ wellcome!!