📄 drag-drop-folder-tree.js
字号:
/************************************************************************************************************
Drag and drop folder tree
Copyright (C) 2006 DTHMLGoodies.com, Alf Magne Kalleland
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Dhtmlgoodies.com., hereby disclaims all copyright interest in this script
written by Alf Magne Kalleland.
Alf Magne Kalleland, 2006
Owner of DHTMLgoodies.com
************************************************************************************************************/
var JSTreeObj;
var treeUlCounter = 0;
var nodeId = 1;
/* Constructor */
function JSDragDropTree()
{
var idOfTree;
var imageFolder;
var folderImage;
var plusImage;
var minusImage;
var maximumDepth;
var dragNode_source;
var dragNode_parent;
var dragNode_sourceNextSib;
var dragNode_noSiblings;
var ajaxObjects;
var dragNode_destination;
var floatingContainer;
var dragDropTimer;
var dropTargetIndicator;
var insertAsSub;
var indicator_offsetX;
var indicator_offsetX_sub;
var indicator_offsetY;
this.imageFolder = 'images/';
this.folderImage = 'dhtmlgoodies_folder.gif';
this.plusImage = 'dhtmlgoodies_plus.gif';
this.minusImage = 'dhtmlgoodies_minus.gif';
this.maximumDepth = 6;
var messageMaximumDepthReached;
var filePathRenameItem;
var filePathDeleteItem;
var additionalRenameRequestParameters = {};
var additionalDeleteRequestParameters = {};
var renameAllowed;
var deleteAllowed;
var currentlyActiveItem;
var contextMenu;
var currentItemToEdit; // Reference to item currently being edited(example: renamed)
var helpObj;
this.contextMenu = false;
this.floatingContainer = document.createElement('UL');
this.floatingContainer.style.position = 'absolute';
this.floatingContainer.style.display='none';
this.floatingContainer.id = 'floatingContainer';
this.insertAsSub = false;
document.body.appendChild(this.floatingContainer);
this.dragDropTimer = -1;
this.dragNode_noSiblings = false;
this.currentItemToEdit = false;
if(document.all){
this.indicator_offsetX = 2; // Offset position of small black lines indicating where nodes would be dropped.
this.indicator_offsetX_sub = 4;
this.indicator_offsetY = 2;
}else{
this.indicator_offsetX = 1; // Offset position of small black lines indicating where nodes would be dropped.
this.indicator_offsetX_sub = 3;
this.indicator_offsetY = 2;
}
if(navigator.userAgent.indexOf('Opera')>=0){
this.indicator_offsetX = 2; // Offset position of small black lines indicating where nodes would be dropped.
this.indicator_offsetX_sub = 3;
this.indicator_offsetY = -7;
}
this.messageMaximumDepthReached = ''; // Use '' if you don't want to display a message
this.renameAllowed = true;
this.deleteAllowed = true;
this.currentlyActiveItem = false;
this.filePathRenameItem = 'folderTree_updateItem.php';
this.filePathDeleteItem = 'folderTree_updateItem.php';
this.ajaxObjects = new Array();
this.helpObj = false;
this.RENAME_STATE_BEGIN = 1;
this.RENAME_STATE_CANCELED = 2;
this.RENAME_STATE_REQUEST_SENDED = 3;
this.renameState = null;
}
/* JSDragDropTree class */
JSDragDropTree.prototype = {
// {{{ addEvent()
/**
*
* This function adds an event listener to an element on the page.
*
* @param Object whichObject = Reference to HTML element(Which object to assigne the event)
* @param String eventType = Which type of event, example "mousemove" or "mouseup"
* @param functionName = Name of function to execute.
*
* @public
*/
addEvent : function(whichObject,eventType,functionName)
{
if(whichObject.attachEvent){
whichObject['e'+eventType+functionName] = functionName;
whichObject[eventType+functionName] = function(){whichObject['e'+eventType+functionName]( window.event );}
whichObject.attachEvent( 'on'+eventType, whichObject[eventType+functionName] );
} else
whichObject.addEventListener(eventType,functionName,false);
}
// }}}
,
// {{{ removeEvent()
/**
*
* This function removes an event listener from an element on the page.
*
* @param Object whichObject = Reference to HTML element(Which object to assigne the event)
* @param String eventType = Which type of event, example "mousemove" or "mouseup"
* @param functionName = Name of function to execute.
*
* @public
*/
removeEvent : function(whichObject,eventType,functionName)
{
if(whichObject.detachEvent){
whichObject.detachEvent('on'+eventType, whichObject[eventType+functionName]);
whichObject[eventType+functionName] = null;
} else
whichObject.removeEventListener(eventType,functionName,false);
}
,
Get_Cookie : function(name) {
var start = document.cookie.indexOf(name+"=");
var len = start+name.length+1;
if ((!start) && (name != document.cookie.substring(0,name.length))) return null;
if (start == -1) return null;
var end = document.cookie.indexOf(";",len);
if (end == -1) end = document.cookie.length;
return unescape(document.cookie.substring(len,end));
}
,
// This function has been slightly modified
Set_Cookie : function(name,value,expires,path,domain,secure) {
expires = expires * 60*60*24*1000;
var today = new Date();
var expires_date = new Date( today.getTime() + (expires) );
var cookieString = name + "=" +escape(value) +
( (expires) ? ";expires=" + expires_date.toGMTString() : "") +
( (path) ? ";path=" + path : "") +
( (domain) ? ";domain=" + domain : "") +
( (secure) ? ";secure" : "");
document.cookie = cookieString;
}
,
setFileNameRename : function(newFileName)
{
this.filePathRenameItem = newFileName;
}
,
setFileNameDelete : function(newFileName)
{
this.filePathDeleteItem = newFileName;
}
,
setAdditionalRenameRequestParameters : function(requestParameters)
{
this.additionalRenameRequestParameters = requestParameters;
}
,
setAdditionalDeleteRequestParameters : function(requestParameters)
{
this.additionalDeleteRequestParameters = requestParameters;
}
,setRenameAllowed : function(renameAllowed)
{
this.renameAllowed = renameAllowed;
}
,
setDeleteAllowed : function(deleteAllowed)
{
this.deleteAllowed = deleteAllowed;
}
,setMaximumDepth : function(maxDepth)
{
this.maximumDepth = maxDepth;
}
,setMessageMaximumDepthReached : function(newMessage)
{
this.messageMaximumDepthReached = newMessage;
}
,
setImageFolder : function(path)
{
this.imageFolder = path;
}
,
setFolderImage : function(imagePath)
{
this.folderImage = imagePath;
}
,
setPlusImage : function(imagePath)
{
this.plusImage = imagePath;
}
,
setMinusImage : function(imagePath)
{
this.minusImage = imagePath;
}
,
setTreeId : function(idOfTree)
{
this.idOfTree = idOfTree;
}
,
expandAll : function()
{
var menuItems = document.getElementById(this.idOfTree).getElementsByTagName('LI');
for(var no=0;no<menuItems.length;no++){
var subItems = menuItems[no].getElementsByTagName('UL');
if(subItems.length>0 && subItems[0].style.display!='block'){
JSTreeObj.showHideNode(false,menuItems[no].id);
}
}
}
,
collapseAll : function()
{
var menuItems = document.getElementById(this.idOfTree).getElementsByTagName('LI');
for(var no=0;no<menuItems.length;no++){
var subItems = menuItems[no].getElementsByTagName('UL');
if(subItems.length>0 && subItems[0].style.display=='block'){
JSTreeObj.showHideNode(false,menuItems[no].id);
}
}
}
,
/*
Find top pos of a tree node
*/
getTopPos : function(obj){
var top = obj.offsetTop/1;
while((obj = obj.offsetParent) != null){
if(obj.tagName!='HTML')top += obj.offsetTop;
}
if(document.all)top = top/1 + 13; else top = top/1 + 4;
return top;
}
,
/*
Find left pos of a tree node
*/
getLeftPos : function(obj){
var left = obj.offsetLeft/1 + 1;
while((obj = obj.offsetParent) != null){
if(obj.tagName!='HTML')left += obj.offsetLeft;
}
if(document.all)left = left/1 - 2;
return left;
}
,
showHideNode : function(e,inputId)
{
if(inputId){
if(!document.getElementById(inputId))return;
thisNode = document.getElementById(inputId).getElementsByTagName('IMG')[0];
}else {
thisNode = this;
if(this.tagName=='A')thisNode = this.parentNode.getElementsByTagName('IMG')[0];
}
if(thisNode.style.visibility=='hidden')return;
var parentNode = thisNode.parentNode;
inputId = parentNode.id.replace(/[^0-9]/g,'');
if(thisNode.src.indexOf(JSTreeObj.plusImage)>=0){
thisNode.src = thisNode.src.replace(JSTreeObj.plusImage,JSTreeObj.minusImage);
var ul = parentNode.getElementsByTagName('UL')[0];
ul.style.display='block';
if(!initExpandedNodes)initExpandedNodes = ',';
if(initExpandedNodes.indexOf(',' + inputId + ',')<0) initExpandedNodes = initExpandedNodes + inputId + ',';
}else{
thisNode.src = thisNode.src.replace(JSTreeObj.minusImage,JSTreeObj.plusImage);
parentNode.getElementsByTagName('UL')[0].style.display='none';
initExpandedNodes = initExpandedNodes.replace(',' + inputId,'');
}
JSTreeObj.Set_Cookie('dhtmlgoodies_expandedNodes',initExpandedNodes,500);
return false;
}
,
/* Initialize drag */
initDrag : function(e)
{
if(document.all)e = event;
var subs = JSTreeObj.floatingContainer.getElementsByTagName('LI');
if(subs.length>0){
if(JSTreeObj.dragNode_sourceNextSib){
JSTreeObj.dragNode_parent.insertBefore(JSTreeObj.dragNode_source,JSTreeObj.dragNode_sourceNextSib);
}else{
JSTreeObj.dragNode_parent.appendChild(JSTreeObj.dragNode_source);
}
}
JSTreeObj.dragNode_source = this.parentNode;
JSTreeObj.dragNode_parent = this.parentNode.parentNode;
JSTreeObj.dragNode_sourceNextSib = false;
if(JSTreeObj.dragNode_source.nextSibling)JSTreeObj.dragNode_sourceNextSib = JSTreeObj.dragNode_source.nextSibling;
JSTreeObj.dragNode_destination = false;
JSTreeObj.dragDropTimer = 0;
JSTreeObj.timerDrag();
return false;
}
,
timerDrag : function()
{
if(this.dragDropTimer>=0 && this.dragDropTimer<10){
this.dragDropTimer = this.dragDropTimer + 1;
setTimeout('JSTreeObj.timerDrag()',20);
return;
}
if(this.dragDropTimer==10)
{
JSTreeObj.floatingContainer.style.display='block';
JSTreeObj.floatingContainer.appendChild(JSTreeObj.dragNode_source);
}
}
,
moveDragableNodes : function(e)
{
if(JSTreeObj.dragDropTimer<10)return;
if(document.all)e = event;
dragDrop_x = e.clientX/1 + 5 + document.body.scrollLeft;
dragDrop_y = e.clientY/1 + 5 + document.documentElement.scrollTop;
JSTreeObj.floatingContainer.style.left = dragDrop_x + 'px';
JSTreeObj.floatingContainer.style.top = dragDrop_y + 'px';
var thisObj = this;
if(thisObj.tagName=='A' || thisObj.tagName=='IMG')thisObj = thisObj.parentNode;
JSTreeObj.dragNode_noSiblings = false;
var tmpVar = thisObj.getAttribute('noSiblings');
if(!tmpVar)tmpVar = thisObj.noSiblings;
if(tmpVar=='true')JSTreeObj.dragNode_noSiblings=true;
if(thisObj && thisObj.id)
{
JSTreeObj.dragNode_destination = thisObj;
var img = thisObj.getElementsByTagName('IMG')[1];
var tmpObj= JSTreeObj.dropTargetIndicator;
tmpObj.style.display='block';
var eventSourceObj = this;
if(JSTreeObj.dragNode_noSiblings && eventSourceObj.tagName=='IMG')eventSourceObj = eventSourceObj.nextSibling;
var tmpImg = tmpObj.getElementsByTagName('IMG')[0];
if(this.tagName=='A' || JSTreeObj.dragNode_noSiblings){
tmpImg.src = tmpImg.src.replace('ind1','ind2');
JSTreeObj.insertAsSub = true;
tmpObj.style.left = (JSTreeObj.getLeftPos(eventSourceObj) + JSTreeObj.indicator_offsetX_sub) + 'px';
}else{
tmpImg.src = tmpImg.src.replace('ind2','ind1');
JSTreeObj.insertAsSub = false;
tmpObj.style.left = (JSTreeObj.getLeftPos(eventSourceObj) + JSTreeObj.indicator_offsetX) + 'px';
}
tmpObj.style.top = (JSTreeObj.getTopPos(thisObj) + JSTreeObj.indicator_offsetY) + 'px';
}
return false;
}
,
dropDragableNodes:function()
{
if(JSTreeObj.dragDropTimer<10){
JSTreeObj.dragDropTimer = -1;
return;
}
var showMessage = false;
if(JSTreeObj.dragNode_destination){ // Check depth
var countUp = JSTreeObj.dragDropCountLevels(JSTreeObj.dragNode_destination,'up');
var countDown = JSTreeObj.dragDropCountLevels(JSTreeObj.dragNode_source,'down');
var countLevels = countUp/1 + countDown/1 + (JSTreeObj.insertAsSub?1:0);
if(countLevels>JSTreeObj.maximumDepth){
JSTreeObj.dragNode_destination = false;
showMessage = true; // Used later down in this function
}
}
if(JSTreeObj.dragNode_destination){
if(JSTreeObj.insertAsSub){
var uls = JSTreeObj.dragNode_destination.getElementsByTagName('UL');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -