這篇文章接續拖曳物件的教學
利用之前寫好的架構再接續較複雜的行為
示範的目標是一水平排列的清單內容,並做到藉由拖曳清單項目改變其排列順序
首先準備好兩種CSS,分別給一般狀態以及拖曳中狀態下的清單項目使用
.undrag {
position:relative;
z-index: 1;
opacity: 1;
filter: alpha(opacity=100);
top: 0px;
left: 0px;
cursor: pointer;
}
.drag {
z-index: 100;
position:absolute;
opacity: .50;
filter: alpha(opacity=50);
cursor: move;
}
要撰寫使用的callback function需先設置幾個全域變數
sourceList 即是來源清單,因清單中除了要套上拖曳行為的標籤外還有其餘元素
所以在額外設置了 sourceLinks 暫存那些標籤,用來建立dragObject
placeHolder為一跟被拖曳的物件同等大小、用來佔位置的物件
placeHolder的class不套用drag/undrag,其餘同一般標籤
最後拖曳行為結束後會將被拖曳的元素放到 placeHolder 所佔的位置上
undragLinks 存放的元素較 sourceLinks 少了正在被拖曳中的元素,以方便實作排序
dragArray儲存拖曳物件,最後須要靠它解除拖曳的設置
var sourceList, placeHolder, sourceLinks, undragLinks, dragArray;
function sortTabs() {
if (dragArray) return;
sourceList = document.getElementById("topTabs");
sourceLinks = document.getElementsByClassName("undrag");
dragArray = [];
placeHolder = document.createElement("DIV");
placeHolder.className = "Tab";
placeHolder.style.backgroundColor = "rgb(225,225,225)";
for (var i = 0; i < sourceLinks.length; i++) {
dragArray.push(new dragObject(sourceLinks[i], itemDragBegin, itemMoved, itemDragEnd));
}
}
function itemDragBegin(e, element) {
element.style.top = element.offsetTop + 'px';
element.style.left = element.offsetLeft + 'px';
element.className = element.className.replace("undrag", "drag");
undragLinks = document.getElementsByClassName("undrag");
sourceList.insertBefore(placeHolder, element);
placeHolder.innerHTML = element.innerHTML;
placeHolder.style.visibility = "hidden";
return {
orientation: "horizontal",
upperLimit: sourceList.getBoundingClientRect().right,
lowerLimit: sourceList.getBoundingClientRect().left
};
}
在move callback function實作排序
因這次是排序水平標籤,所以設定當拖曳的物件移動的範圍到前、後物件一半的寬度就交換位置
function itemMoved(e, element) {
e = e || window.event;
var elementPos = element.getBoundingClientRect();
var elementLeft = elementPos.left;
var elementRight = elementPos.right;
var placeHolderPos = placeHolder.getBoundingClientRect();
var moveRight = elementLeft >= placeHolderPos.left;
var itemPos;
for (var i = 0; i < undragLinks.length; i++) {
itemPos = undragLinks[i].getBoundingClientRect();
if (moveRight) {
if(itemPos.right <= placeHolderPos.left) continue;
if(elementRight > itemPos.left + undragLinks[i].offsetWidth * 0.5) {
sourceList.insertBefore(undragLinks[i], placeHolder);
break;
}
} else {
if(itemPos.right - undragLinks[i].offsetWidth * 0.5 > elementLeft) {
sourceList.insertBefore(placeHolder, undragLinks[i]);
break;
}
}
}
//prevent cursor move too fast that move callback function is not invoked as much times as it should be
var maxScrollLeft = sourceList.scrollWidth - sourceList.clientWidth;
if (elementRight > $("sideCreateNewApp").getBoundingClientRect().left) {
topTabsScrollRight();
if(sourceList.scrollLeft == maxScrollLeft) sourceList.appendChild(placeHolder);
} else if (elementLeft - element.offsetWidth * 0.5 < sourceList.getBoundingClientRect().left) {
topTabsScrollLeft();
if(sourceList.scrollLeft == 0) sourceList.insertBefore(placeHolder, undragLinks[0]);
}
}
function itemDragEnd(e, element) {
sourceList.replaceChild(element, placeHolder);
element.className = element.className.replace("drag", "undrag");
element.style.top = '0px';
element.style.left = '0px';
}
用完之後的清理動作
for(var i = 0; i < dragArray.length; i++){
dragArray[i].dispose();
}
dragArray = null;
利用之前寫好的架構再接續較複雜的行為
示範的目標是一水平排列的清單內容,並做到藉由拖曳清單項目改變其排列順序
首先準備好兩種CSS,分別給一般狀態以及拖曳中狀態下的清單項目使用
.undrag {
position:relative;
z-index: 1;
opacity: 1;
filter: alpha(opacity=100);
top: 0px;
left: 0px;
cursor: pointer;
}
.drag {
z-index: 100;
position:absolute;
opacity: .50;
filter: alpha(opacity=50);
cursor: move;
}
要撰寫使用的callback function需先設置幾個全域變數
sourceList 即是來源清單,因清單中除了要套上拖曳行為的標籤外還有其餘元素
所以在額外設置了 sourceLinks 暫存那些標籤,用來建立dragObject
placeHolder為一跟被拖曳的物件同等大小、用來佔位置的物件
placeHolder的class不套用drag/undrag,其餘同一般標籤
最後拖曳行為結束後會將被拖曳的元素放到 placeHolder 所佔的位置上
undragLinks 存放的元素較 sourceLinks 少了正在被拖曳中的元素,以方便實作排序
dragArray儲存拖曳物件,最後須要靠它解除拖曳的設置
var sourceList, placeHolder, sourceLinks, undragLinks, dragArray;
function sortTabs() {
if (dragArray) return;
sourceList = document.getElementById("topTabs");
sourceLinks = document.getElementsByClassName("undrag");
dragArray = [];
placeHolder = document.createElement("DIV");
placeHolder.className = "Tab";
placeHolder.style.backgroundColor = "rgb(225,225,225)";
for (var i = 0; i < sourceLinks.length; i++) {
dragArray.push(new dragObject(sourceLinks[i], itemDragBegin, itemMoved, itemDragEnd));
}
}
function itemDragBegin(e, element) {
element.style.top = element.offsetTop + 'px';
element.style.left = element.offsetLeft + 'px';
element.className = element.className.replace("undrag", "drag");
undragLinks = document.getElementsByClassName("undrag");
sourceList.insertBefore(placeHolder, element);
placeHolder.innerHTML = element.innerHTML;
placeHolder.style.visibility = "hidden";
return {
orientation: "horizontal",
upperLimit: sourceList.getBoundingClientRect().right,
lowerLimit: sourceList.getBoundingClientRect().left
};
}
在move callback function實作排序
因這次是排序水平標籤,所以設定當拖曳的物件移動的範圍到前、後物件一半的寬度就交換位置
function itemMoved(e, element) {
e = e || window.event;
var elementPos = element.getBoundingClientRect();
var elementLeft = elementPos.left;
var elementRight = elementPos.right;
var placeHolderPos = placeHolder.getBoundingClientRect();
var moveRight = elementLeft >= placeHolderPos.left;
var itemPos;
for (var i = 0; i < undragLinks.length; i++) {
itemPos = undragLinks[i].getBoundingClientRect();
if (moveRight) {
if(itemPos.right <= placeHolderPos.left) continue;
if(elementRight > itemPos.left + undragLinks[i].offsetWidth * 0.5) {
sourceList.insertBefore(undragLinks[i], placeHolder);
break;
}
} else {
if(itemPos.right - undragLinks[i].offsetWidth * 0.5 > elementLeft) {
sourceList.insertBefore(placeHolder, undragLinks[i]);
break;
}
}
}
//prevent cursor move too fast that move callback function is not invoked as much times as it should be
var maxScrollLeft = sourceList.scrollWidth - sourceList.clientWidth;
if (elementRight > $("sideCreateNewApp").getBoundingClientRect().left) {
topTabsScrollRight();
if(sourceList.scrollLeft == maxScrollLeft) sourceList.appendChild(placeHolder);
} else if (elementLeft - element.offsetWidth * 0.5 < sourceList.getBoundingClientRect().left) {
topTabsScrollLeft();
if(sourceList.scrollLeft == 0) sourceList.insertBefore(placeHolder, undragLinks[0]);
}
}
function itemDragEnd(e, element) {
sourceList.replaceChild(element, placeHolder);
element.className = element.className.replace("drag", "undrag");
element.style.top = '0px';
element.style.left = '0px';
}
用完之後的清理動作
for(var i = 0; i < dragArray.length; i++){
dragArray[i].dispose();
}
dragArray = null;
留言
張貼留言