JavaScript实现可通过拖拽进行重排的文章列表

2008-12-30 09:39:08 | 【

本范例演示了一个可对文本列表进行拖拽重排的脚本功能,在做文章列表排序时非常有用,用户可以直接用鼠标对文章标题进行拖拽排序,该脚本可以在ie,firefox等浏览器中运行

查看演示页面 View Demo 查看全部代码 View Code

在网页<head>区添加以下代码

<style type="text/css">
	body{
		font-family: Trebuchet MS, Lucida Sans Unicode, Arial, sans-serif;
		margin:0px;
		padding:0px;
		background-image:url('http://www.sharejs.com/images/logo.gif');
		background-repeat:no-repeat;
		padding-top:85px;					
		overflow:hidden;
		padding-left:10px;
		-moz-user-select:no;
	}
	
	/* Don't change these options */
	#movableNode{
		position:absolute;
	}
	
	#arrDestInditcator{
		position:absolute;
		display:none;
		width:100px;
	}
	/* End options that shouldn't be changed */

	
	#arrangableNodes,#movableNode ul{
		padding-left:0px;
		margin-left:0px;
		margin-top:0px;
		padding-top:0px;
	}
	
	#arrangableNodes li,#movableNode li{
		list-style-type:none;
		cursor:default;
	}

	</style>
	
	<script type="text/javascript">
	/************************************************************************************************************
	(C) www.dhtmlgoodies.com, October 2005
	Download from sharejs.com
	This is a script from www.dhtmlgoodies.com. You will find this and a lot of other scripts at our website.	
	
	Terms of use:
	You are free to use this script as long as the copyright message is kept intact. However, you may not
	redistribute, sell or repost it without our permission.
	
	Thank you!
	
	www.dhtmlgoodies.com
	Alf Magne Kalleland
	
	************************************************************************************************************/	
	
	var offsetYInsertDiv = -3; // Y offset for the little arrow indicating where the node should be inserted.
	if(!document.all)offsetYInsertDiv = offsetYInsertDiv - 7; 	// No IE

	
	var arrParent = false;
	var arrMoveCont = false;
	var arrMoveCounter = -1;
	var arrTarget = false;
	var arrNextSibling = false;
	var leftPosArrangableNodes = false;
	var widthArrangableNodes = false;
	var nodePositionsY = new Array();
	var nodeHeights = new Array();
	var arrInsertDiv = false;
	var insertAsFirstNode = false;
	var arrNodesDestination = false;
	function cancelEvent()
	{
		return false;
	}
	function getTopPos(inputObj)
	{
		
	  var returnValue = inputObj.offsetTop;
	  while((inputObj = inputObj.offsetParent) != null){
	  	returnValue += inputObj.offsetTop;
	  }
	  return returnValue;
	}
	
	function getLeftPos(inputObj)
	{
	  var returnValue = inputObj.offsetLeft;
	  while((inputObj = inputObj.offsetParent) != null)returnValue += inputObj.offsetLeft;
	  return returnValue;
	}
		
	function clearMovableDiv()
	{
		if(arrMoveCont.getElementsByTagName('LI').length>0){
			if(arrNextSibling)arrParent.insertBefore(arrTarget,arrNextSibling); else arrParent.appendChild(arrTarget);			
		}
		
	}
	
	function initMoveNode(e)
	{
		clearMovableDiv();
		if(document.all)e = event;
		arrMoveCounter = 0;
		arrTarget = this;
		if(this.nextSibling)arrNextSibling = this.nextSibling; else arrNextSibling = false;
		timerMoveNode();
		arrMoveCont.parentNode.style.left = e.clientX + 'px';
		arrMoveCont.parentNode.style.top = e.clientY + 'px';
		return false;
		
	}
	function timerMoveNode()
	{
		if(arrMoveCounter>=0 && arrMoveCounter<10){
			arrMoveCounter = arrMoveCounter +1;
			setTimeout('timerMoveNode()',20);
		}
		if(arrMoveCounter>=10){
			arrMoveCont.appendChild(arrTarget);
		}
	}
		
	function arrangeNodeMove(e)
	{
		if(document.all)e = event;
		if(arrMoveCounter<10)return;
		if(document.all && arrMoveCounter>=10 && e.button!=1 && navigator.userAgent.indexOf('Opera')==-1){
			arrangeNodeStopMove();
		}
		
		arrMoveCont.parentNode.style.left = e.clientX + 'px';
		arrMoveCont.parentNode.style.top = e.clientY + 'px';	
		
		var tmpY = e.clientY;
		arrInsertDiv.style.display='none';
		arrNodesDestination = false;
		

		if(e.clientX<leftPosArrangableNodes || e.clientX>leftPosArrangableNodes + widthArrangableNodes)return; 
			
		var subs = arrParent.getElementsByTagName('LI');
		for(var no=0;no<subs.length;no++){
			var topPos =getTopPos(subs[no]);
			var tmpHeight = subs[no].offsetHeight;
			
			if(no==0){
				if(tmpY<=topPos && tmpY>=topPos-5){
					arrInsertDiv.style.top = (topPos + offsetYInsertDiv) + 'px';
					arrInsertDiv.style.display = 'block';				
					arrNodesDestination = subs[no];	
					insertAsFirstNode = true;
					return;
				}				
			}
			
			if(tmpY>=topPos && tmpY<=(topPos+tmpHeight)){
				arrInsertDiv.style.top = (topPos+tmpHeight + offsetYInsertDiv) + 'px';
				arrInsertDiv.style.display = 'block';				
				arrNodesDestination = subs[no];
				insertAsFirstNode = false;
				return;
			}				
		}
	}
	
	function arrangeNodeStopMove()
	{
		arrMoveCounter = -1; 
		arrInsertDiv.style.display='none';
		
		if(arrNodesDestination){
			var subs = arrParent.getElementsByTagName('LI');
			if(arrNodesDestination==subs[0] && insertAsFirstNode){
				arrParent.insertBefore(arrTarget,arrNodesDestination);		
			}else{
				if(arrNodesDestination.nextSibling){
					arrParent.insertBefore(arrTarget,arrNodesDestination.nextSibling);
				}else{
					arrParent.appendChild(arrTarget);
				}
			}
		}		
		arrNodesDestination = false;
		clearMovableDiv();
	}		
	
	function saveArrangableNodes()
	{
		var nodes = arrParent.getElementsByTagName('LI');
		var string = "";
		for(var no=0;no<nodes.length;no++){
			if(string.length>0)string = string + ',';
			string = string + nodes[no].id;		
		}
		
		document.forms[0].hiddenNodeIds.value = string;
		
		// Just for testing
		document.getElementById('arrDebug').innerHTML = 'Ready to save these nodes:<br>' + string.replace(/,/g,',<BR>');	
		
		// document.forms[0].submit(); // Remove the comment in front of this line when you have set an action to the form.
		
	}
	
	function initArrangableNodes()
	{
		arrParent = document.getElementById('arrangableNodes');
		arrMoveCont = document.getElementById('movableNode').getElementsByTagName('UL')[0];
		arrInsertDiv = document.getElementById('arrDestInditcator');
		
		leftPosArrangableNodes = getLeftPos(arrParent);
		arrInsertDiv.style.left = leftPosArrangableNodes - 5 + 'px';
		widthArrangableNodes = arrParent.offsetWidth;
		
		var subs = arrParent.getElementsByTagName('LI');
		for(var no=0;no<subs.length;no++){
			subs[no].onmousedown = initMoveNode;
			subs[no].onselectstart = cancelEvent;	
		}
	
		document.documentElement.onmouseup = arrangeNodeStopMove;
		document.documentElement.onmousemove = arrangeNodeMove;
		document.documentElement.onselectstart = cancelEvent;
		
	}	
	
	window.onload = initArrangableNodes;
	
	</script>


在网页<body>区添加以下代码

<H1>Arrange the nodes below</H1>
<ul id="arrangableNodes">
	<li id="node1">Node no. 1</li>
	<li id="node2">Node no. 2</li>
	<li id="node3">Node no. 3</li>
	<li id="node4">Node no. 4</li>
	<li id="node5">Node no. 5</li>
	<li id="node6">Node no. 6</li>
	<li id="node7">Node no. 7</li>
	<li id="node8">Node no. 8</li>	
	<li id="node9">Node no. 9</li>	
	<li id="node10">Node no. 10</li>	
	<li id="node11">http://www.sharejs.com</li>	
	<li id="node12">Node no. 12</li>	
	<li id="node13">Node no. 13</li>	
	<li id="node14">Node no. 14</li>	
	<li id="node15">Node no. 15</li>	
</ul>	
<p>
	<a href="#" onclick="saveArrangableNodes();return false">Save</a>
</p>
<div id="movableNode"><ul></ul></div>	
<div id="arrDestInditcator"><img src="images/insert.gif"></div>
<div id="arrDebug"></div>
<form method="post" action="????">
	<input type="hidden" name="hiddenNodeIds">
</form>



下载图片
脚本中用到了一个右箭头图标,点击鼠标右键,另存图片到"images"文件夹下


脚本调用就说明
文本列表必须都包含在<UL id="arrangableNodes"> 标签内部.如:
<ul id="arrangableNodes">
    <li id="node1">Node no. 1</li>
    <li id="node2">Node no. 2</li>
    <li id="node3">Node no. 3</li>
    <li id="node4">Node no. 4</li>
    <li id="node5">Node no. 5</li>
    <li id="node6">Node no. 6</li>
    <li id="node7">Node no. 7</li>
    <li id="node8">Node no. 8</li>    
    <li id="node9">Node no. 9</li>    
    <li id="node10">Node no. 10</li>    
    <li id="node11">Node no. 11</li>    
    <li id="node12">Node no. 12</li>    
    <li id="node13">Node no. 13</li>    
    <li id="node14">Node no. 14</li>    
    <li id="node15">Node no. 15</li>    
</ul> 

每一行文本使用一对<li></li>标签包围,记住,每一个<li>都必须有一个唯一的ID

你还需要修改脚本中的一些JavaScript变量
var offsetYInsertDiv = -3; // 插入结点的小箭头图标的Y偏移量.
if(!document.all)offsetYInsertDiv = offsetYInsertDiv - 7; // 非IE
上面两个变量第一个用于IE,第二个用于firefox. .

保存修改
saveArrangableNodes() 函数用户保存调整后的顺序。 这个函数的功能就是创建一个所有项目的ID的字符串列表. 这个字符串放在"hiddenNodeIds"隐藏字段内。
你需要自己创建一个服务器端的程序来保存调整后的顺序。都准备好了以后,从<head>区移除一下脚本的注释,让表单能够正常提交:
// document.forms[0].submit();



把服务器端的文件路径放到form的action属性
<form method="post" action="????">
    <input type="hidden" name="hiddenNodeIds">
</form>


sharejs.com提示您:
如果希望在点保存的时候页面不刷新,可以使用iframe:
<iframe name="saveIframe" src="serversideFile.html" width="1" height="1" frameborder="no"> 


修改一下form标签,添加target=saveIframe,其中saveiframe是iframe的name,如
<form method="post" action="serversideFile.html" target="saveIframe"


这样提交页面时,页面将不会刷新,直接在IFrame里进行。

哈哈,是不是很棒的脚本

下载"JavaScript实现可通过拖拽进行重排的文章列表"

  • 本地下载
  • 本地下载2

相关资源