script.aculo.us - 元素排序


很多时候,您需要为用户提供通过拖动来重新排序元素(例如列表中的项目)的功能。

如果没有拖放功能,重新排序将是一场噩梦,但是script.aculo.us通过Sortable类开箱即用地提供了扩展的重新排序支持。要成为Sortable的元素将传递给Sortable命名空间中的create()方法。

Sortable由容器元素中的项目元素组成。当您创建新的Sortable时,它会负责创建相应的DraggablesDroppables

要使用script.aculo.us的Sortable功能,您需要加载dragdrop模块,该模块还需要effects模块。因此,您script.aculo.us的最小加载如下所示:

<script type = "text/javascript" src = "/javascript/prototype.js"></script>
<script type = "text/javascript"  src = "/javascript/scriptaculous.js?load = effects,dragdrop"></script>

Sortable语法

这是创建可排序项目的create()方法的语法。create()方法接受容器元素的id,并根据传递的选项对其进行排序。

Sortable.create('id_of_container',[options]);

使用Sortable.destroy完全删除由Sortable.create创建的Sortable的所有事件处理程序和引用。

注意 - 如果引用的元素已经是Sortable,则调用Sortable.create会隐式调用Sortable.destroy。以下是调用destroy函数的简单语法。

Sortable.destroy( element );

Sortable选项

创建Sortable对象时,您可以使用以下一个或多个选项。

序号 选项及说明
1

tag

指定可排序容器内可通过拖放排序的元素的类型。默认为'li'。

2

only

指定一个CSS类名或类名数组,可拖动项目必须拥有该类名才能被放置目标接受。这类似于Draggable的accept选项。默认情况下,不应用任何类名约束。

3

overlap

false、horizontalvertical之一。控制触发重新排序的点。默认为vertical

4

constraint

false、horizontalvertical之一。约束拖动可排序元素的移动。默认为vertical

5

containment

启用在Sortables之间拖放。接受元素或元素ID数组。重要说明:为了确保两个容器之间可以进行双向拖动,请在容器元素之后放置所有Sortable.create调用。

6

handle

与同名的Draggable选项相同,指定用于启动拖动操作的元素。默认情况下,每个元素都是它自己的句柄。

7

hoverclass

指定一个CSS类名,当拖动元素经过时将其应用于未拖动的可排序元素。默认情况下,不应用任何CSS类名。
8

ghosting

类似于同名的Draggable选项,如果为true,此选项会导致拖动操作的原始元素保持原位,而元素的半透明副本将随鼠标指针一起移动。默认为false。此选项不适用于IE。

9

dropOnEmpty

如果为true,则允许将可排序元素放到空列表中。默认为false

10

scroll

如果由于设置CSS overflow属性而可排序容器拥有滚动条,则此选项启用超出可见元素的列表自动滚动。默认为false

12

scrollSensitivity

启用滚动时,它会调整触发滚动的点。默认为20。

13

scrollSpeed

启用滚动时,它会调整滚动速度。默认为15。

14

tree

如果为true,则启用对可排序元素内的子元素进行排序。默认为false。

15

treeTag

如果启用tree选项,则指定子元素的容器元素类型,其子元素参与可排序行为。默认为'ul'。

您可以在options参数中提供以下回调函数

序号 选项及说明
1

onChange

拖动过程中排序顺序发生变化时将调用的函数。从一个Sortable拖动到另一个Sortable时,回调函数将在每个Sortable上调用一次。获取受影响的元素作为其参数。

2

onUpdate

在导致元素顺序发生变化的拖动操作终止时将调用的函数。

排序示例

此演示已验证可在IE 6.0中运行。它也适用于最新版本的Firefox。

<html>
   <head>
      <title>Sorting Example</title>
		
      <script type = "text/javascript" src = "/javascript/prototype.js"></script>
      <script type = "text/javascript" src = "/javascript/scriptaculous.js"></script>
		
      <script type = "text/javascript">
         window.onload = function() {
            Sortable.create('namelist',{tag:'li'});
         }
      </script>

      <style type = "text/css">
         li { cursor: move; }
      </style>
   </head>
   
   <body>
      <p>Drag and drop list items to sort them out</p>

      <ul id = "namelist">
         <li>Physics</li>
         <li>Chemistry</li>
         <li>Maths</li>
         <li>Botany</li>
         <li>Sociology</li>
         <li>English</li>
         <li>Hindi</li>
         <li>Sanskrit</li>
      </ul>
   </body>
</html>

使用我们的在线编译器,结合上表中讨论的不同选项,更好地理解代码。

这将产生以下结果:

请注意tag:'li'的使用。同样,您可以对`

`中提供的以下图像列表进行排序:

<html>
   <head>
      <title>Sorting Example</title>
		
      <script type = "text/javascript" src = "/javascript/prototype.js"></script>
      <script type = "text/javascript" src = "/javascript/scriptaculous.js"></script>
		
      <script type = "text/javascript">
         window.onload = function() {
            Sortable.create('imagelist',{tag:'div'});
         }
      </script>

      <style type = "text/css">
         div { cursor: move; }
         img { border: 1px solid red; margin:5px; }
      </style>
   </head>

   <body>
      <p>Drag and drop list images to re-arrange them</p>

      <div id = "imagelist">
         <div><img src = "/images/wml_logo.gif" alt="WML Logo" /></div>
         <div><img src = "/images/javascript.gif" alt="JS" /></div>
         <div><img src = "/images/html.gif" alt="HTML" /></div>
         <div><img src = "/images/css.gif" alt="CSS" /></div>
      </div>
   </body>
</html>

这将产生以下结果:

序列化可排序元素

Sortable对象还提供一个函数Sortable.serialize(),用于以适合HTTP GET或POST请求的格式序列化Sortable。这可以用于通过Ajax调用提交Sortable的顺序。

语法

Sortable.serialize(element, options);

选项

创建Sortable对象时,您可以使用以下一个或多个选项。

序号 选项及说明
1

tag

设置将被序列化的标签类型。这将类似于Sortable.create中使用的类型。

2

name

设置将用于创建键/值对以进行HTTP GET/POST格式序列化的键的名称。因此,如果name为xyz,则查询字符串将如下所示:

xyz[]=value1 & xyz[]=value2 & xyz[]=value3

其中值来自子元素,其顺序与它们在容器中出现的顺序相同。

序列化示例

在此示例中,序列化的输出将仅提供列表项ID中下划线后的数字。

要尝试,请将列表保持其原始顺序,按按钮查看列表的序列化。现在,重新排序一些元素,然后再次单击按钮。

<html>
   <head>
      <title>Sorting Example</title>
		
      <script type = "text/javascript" src = "/javascript/prototype.js"></script>
      <script type = "text/javascript" src = "/javascript/scriptaculous.js"></script>
		
      <script type = "text/javascript">
         window.onload = function() {
            Sortable.create('namelist',{tag:'li'});
         }

         function serialize(container, name){
            $('display').innerHTML = 'Serialization of ' + 
            $(container).id + 
            ' is: <br/><pre>' + 
               Sortable.serialize( container,{ name:name} ) + 
            '</pre>';
         }
      </script>

      <style type = "text/css">
         li { cursor: move; }
      </style>	
   </head>

   <body>
      <p>Drag and drop list items to sort them out properly</p>

      <ul id = "namelist">
         <li id = "list1_1">Physics</li>
         <li id = "list1_2">Chemistry</li>
         <li id = "list1_3">Maths</li>
         <li id = "list1_4">Botany</li>
         <li id = "list1_5">Sociology</li>
         <li id = "list1_6">English</li>
      </ul>

      <p>Click following button to see serialized list which can be
         passed to backend script, like PHP, AJAX or CGI</p>
			
      <button type = "button" value = "Click Me" 
         onclick = "serialize('namelist', 'list')"> Serialize
      </button>

      <div id = "display" style = "clear:both;padding-top:32px"></div>
   </body>
</html>

这将产生以下结果:

在Sortables之间移动项目

以下示例显示如何将项目从一个列表移动到另一个列表。

<html>
   <head>
      <title>Sorting Example</title>
		
      <script type = "text/javascript" src = "/javascript/prototype.js"></script>
      <script type = "text/javascript" src = "/javascript/scriptaculous.js"></script>
		
      <script type = "text/javascript">
         window.onload = function() {
            Sortable.create('List1', {containment: ['List1','List2'], dropOnEmpty: true});

            Sortable.create('List2', {containment: ['List1','List2'], dropOnEmpty: true});
         }
      </script>

      <style type = "text/css">
         li { cursor: move; }
         ul {
            width: 88px;
            border: 1px solid blue;
            padding: 3px 3px 3px 20px;
         }
      </style>		
   </head>

   <body>
      <p>Drag and drop list items from one list to another list</p>

      <div style = "float:left">
         <ul id = "List1">
            <li>Physics</li>
            <li>Chemistry</li>
            <li>Botany</li>
         </ul>
      </div>

      <div style = "float:left;margin-left:32px">
         <ul id = "List2">
            <li>Arts</li>
            <li>Politics</li>
            <li>Economics</li>
            <li>History</li>
            <li>Sociology</li>
         </ul>
      </div>
   </body>
</html>

请注意,每个容器的containment选项都将两个容器列为包含元素。通过这样做,我们使子元素能够在其父级上下文中进行排序;它还使它们能够在两个容器之间移动。

我们将两个列表的dropOnEmpty设置为true。要查看此选项对该列表的影响,请将所有元素从一个列表移动到另一个列表,以便一个列表为空。您会发现它允许将元素放到空列表中。

这将产生以下结果:

绑定到Ajax

当然,onUpdate是触发对服务器的Ajax通知的主要候选者,例如,当用户重新排序待办事项列表或其他一些数据集时。结合Ajax.RequestSortable.serialize使实时持久化足够简单:

<html>
   <head>
      <title>Sorting Example</title>
		
      <script type = "text/javascript" src = "/javascript/prototype.js"></script>
      <script type = "text/javascript" src = "/javascript/scriptaculous.js"></script>
      
      <script type = "text/javascript">
         window.onload = function() {
            Sortable.create('List' ,
               {
                  onUpdate: function() {
                     new Ajax.Request('file.php',
                        {
                           method: "post",
                           parameters: {data:Sortable.serialize('List')}
                        }
                     );
                  }
               }
            );
         }
      </script>

      <style type = "text/css">
         li { cursor: move; }
         ul {
            width: 88px;
            border: 1px solid blue;
            padding: 3px 3px 3px 20px;
         }
      </style>
   </head>

   <body>
      <p>When you will change the order, AJAX Request 
         will be made automatically.</p>

      <div style = "float:left">
         <ul id = "List">
            <li id = "List_1">Physics</li>
            <li id = "List_2">Chemistry</li>
            <li id = "List_3">Maths</li>
            <li id = "List_4">Botany</li>
         </ul>
      </div>
   </body>
</html>

Sortable.serialize创建类似这样的字符串:List[] = 1 & List[] = 2 & List[] = 3 &List[] = 4,其中数字是列表元素ID在下划线之后的部分标识符。

现在我们需要编写file.php代码,它将解析作为parse_str($_POST['data']);发布的数据,您可以对这个排序后的数据执行任何操作。

要了解有关AJAX的更多信息,请阅读我们简单的Ajax教程

广告