[转帖]Mootools源码分析-44 -- Sortables

it2022-05-11  59

原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-409214

原作者:我佛山人

 

代码 // 拖放排序类 // 演示:http://demos.mootools.net/Sortables var  Sortables  =   new  Class({     // 继承自Events和Options,UI插件的特点     Implements: [Events, Options],    options: { /*         //排序事件        onSort: $empty,        //开始事件        onStart: $empty,        //完成事件        onComplete: $empty, */         snap:  4 ,         // 透明度         opacity:  1 ,         // 是否复制         clone:  false ,         // 是否使用形变动画         revert:  false ,         // 拖动句柄对象         handle:  false ,         // 约束         constrain:  false     },     // 构造函数     initialize:  function (lists, options)    {         // 设置配置参数          this .setOptions(options);         this .elements  =  [];         this .lists  =  [];         this .idle  =   true ;         // 列表项可以单个,也可以是符合          this .addLists($$($(lists)  ||  lists));         // 如果不克隆副本,则不需要变形动画          if  ( ! this .options.clone)     this .options.revert  =   false ;         // 如果指定变形动画效果          if  ( this .options.revert)  this .effect  =   new  Fx.Morph( null , $merge({duration:  250 , link:  ' cancel ' },  this .options.revert));    },     // 附加事件     attach:  function ()    {         this .addLists( this .lists);         return   this ;    },     // 移除事件     detach:  function ()    {         this .lists  =   this .removeLists( this .lists);         return   this ;    },     // 添加列表项     addItems:  function ()    {         // 给参数降维再遍历         Array.flatten(arguments).each( function (element)    {             // 加到数组              this .elements.push(element);             // 将关联本列表项的start方法缓存              var  start  =  element.retrieve( ' sortables:start ' this .start.bindWithEvent( this , element));             // 如果指定拖动句柄,从当前列表项中获取,否则将当前列表项作为句柄              // 然后给句柄添加鼠标按下事件,触发start方法             ( this .options.handle  ?  element.getElement( this .options.handle)  ||  element : element).addEvent( ' mousedown ' , start);        },  this );     return   this ;    },     // 添加列表     addLists:  function ()    {         // 给参数降维再遍历         Array.flatten(arguments).each( function (list)    {             this .lists.push(list);             // 添加当前列表下的项              this .addItems(list.getChildren());        },  this );         return   this ;    },     // 移除列表项     removeItems:  function ()    {         // 用于返回的数组          var  elements  =  [];         // 给参数降维再遍历         Array.flatten(arguments).each( function (element)    {             // 加到返回数组             elements.push(element);             // 从数组中删除              this .elements.erase(element);             // 取缓存中的事件绑定方法              var  start  =  element.retrieve( ' sortables:start ' );             // 类似添加列表项时的判断,找到句柄后移除事件             ( this .options.handle  ?  element.getElement( this .options.handle)  ||  element : element).removeEvent( ' mousedown ' , start);        },  this );         // 返回移除的列表项集合          return  $$(elements);    },     // 移除列表     removeLists:  function ()    {         // 用于返回的数组          var  lists  =  [];         // 给参数降维再遍历         Array.flatten(arguments).each( function (list)    {             // 加到返回数组             lists.push(list);             // 从数组中删除              this .lists.erase(list);             // 移除当前列表的所有列表项,因为removeItems方法中自动给参数降维,所以可以直接传数组              this .removeItems(list.getChildren());        },  this );         // 返回移除的列表集合          return  $$(lists);    },     // 获取复制的对象     getClone:  function (event, element)    {         // 如果指定不复制,返回新创建的div并插入到body          if  ( ! this .options.clone)     return   new  Element( ' div ' ).inject(document.body);         // 如果参数为函数,修改其调用的上下文指向并传送指定参数          if  ($type( this .options.clone)  ==   ' function ' )     return   this .options.clone.call( this , event, element,  this .list);         // 剩下的是指定为复制的情况          // 复制当前列表项并修改其样式          return  element.clone( true ).setStyles({                 ' margin ' ' 0px ' ,                 ' position ' ' absolute ' ,                 ' visibility ' ' hidden ' ,                 ' width ' : element.getStyle( ' width ' )        }).inject( this .list).position(element.getPosition(element.offsetParent));    },     // 获取可放落的对象     getDroppables:  function ()    {         // 取当前列表下的所有列表项          var  droppables  =   this .list.getChildren();         // 如果没有约束,则其它列表也作为可放落对象          if  ( ! this .options.constrain)    droppables  =   this .lists.concat(droppables).erase( this .list);         // 从可放落对象集合中排除当前对象及其克隆          return  droppables.erase( this .clone).erase( this .element);    },     // 插入     insert:  function (dragging, element)    {         // 指定插入位置          var  where  =   ' inside ' ;         if  ( this .lists.contains(element))    {             this .list  =  element;             this .drag.droppables  =   this .getDroppables();        }     else     {            where  =   this .element.getAllPrevious().contains(element)  ?   ' before '  :  ' after ' ;        }         this .element.inject(element, where);         this .fireEvent( ' onSort ' , [ this .element,  this .clone]);    },     // 开始操作     start:  function (event, element)    {         // 如果当前非闲置状态,退出          if  ( ! this .idle)     return ;         // 设置闲置状态标识          this .idle  =   false ;         // 当前操作对象          this .element  =  element;         // 获取当前透明度          this .opacity  =  element.get( ' opacity ' );         // 获取当前操作对象所在的列表对象          this .list  =  element.getParent();         // 获取当前操作对象的克隆对象          this .clone  =   this .getClone(event, element);         // 创建拖放对象          this .drag  =   new  Drag.Move( this .clone, {            snap:  this .options.snap,             // 拖放范围,如果指定constrain参数为true才会取当前对象所在的列表对象             container:  this .options.constrain  &&   this .element.getParent(),             // 获取可放落的对象             droppables:  this .getDroppables(),             // onSnap事件监听             onSnap:  function ()    {                 // 停止事件冒泡及返回值                 event.stop();                 // 显示克隆对象                  this .clone.setStyle( ' visibility ' ' visible ' );                 // 设置透明度                  this .element.set( ' opacity ' this .options.opacity  ||   0 );                 // 触发onStart事件                  this .fireEvent( ' onStart ' , [ this .element,  this .clone]);            }.bind( this ),             // 拖动进入事件             onEnter:  this .insert.bind( this ),             // 取消拖动事件             onCancel:  this .reset.bind( this ),             // 拖动完成事件             onComplete:  this .end.bind( this )        });         // 插入克隆对象到当前对象前面          this .clone.inject( this .element,  ' before ' );         // 开始拖动          this .drag.start(event);    },     // 结束拖动排序     end:  function ()    {         // 移除事件          this .drag.detach();         // 恢复透明度          this .element.set( ' opacity ' this .opacity);         // 如果使用形变动画(主要是外形尺寸和坐标位置上的)          if  ( this .effect)    {             // 获取尺寸              var  dim  =   this .element.getStyles( ' width ' ' height ' );             // 计算位置              var  pos  =   this .clone.computePosition( this .element.getPosition( this .clone.offsetParent));             // 将当前克隆对象作为形变对象              this .effect.element  =   this .clone;             // 开始动画效果              this .effect.start({                top: pos.top,                left: pos.left,                width: dim.width,                height: dim.height,                opacity:  0.25                  // 动画完成后的后续操作             }).chain( this .reset.bind( this ));        }     else     {             // 后续操作              this .reset();        }    },     // 重置     reset:  function ()    {         // 设置闲置状态标记          this .idle  =   true ;         // 清除克隆对象          this .clone.destroy();         // 触发onComplete事件          this .fireEvent( ' onComplete ' this .element);    },     // 序列化     serialize:  function ()    {         // 使用Array.link处理参数          var  params  =  Array.link(arguments, {modifier: Function.type, index: $defined});         // 遍历列表集          var  serial  =   this .lists.map( function (list)    {             // 遍历各列表的列表项,如果参数中传有函数的引用,使用该函数处理列表项,否则默认返回id              return  list.getChildren().map(params.modifier  ||   function (element)    {                 // 取列表项的id                  return  element.get( ' id ' );            },  this );        },  this );         // 参数中传送的索引值          var  index  =  params.index;         // 如果列表集中只有一项,则索引值为0          if  ( this .lists.length  ==   1 ) index  =   0 ;         // 如果索引存在并且值在合法范围内,返回指定索引值列表的序列化结果,否则返回整个列表集的序列化结果          return  $chk(index)  &&  index  >=   0   &&  index  <   this .lists.length  ?  serial[index] : serial;    }});

 

转载于:https://www.cnblogs.com/maapaa/articles/mootools-s-44.html

相关资源:mootools-core-1.5.1

最新回复(0)