[转帖]Mootools源码分析-48 -- Slider

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

原作者:我佛山人

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
// 滑动条
//
演示:http://demos.mootools.net/Slider
var  Slider  =   new  Class({

    
// 继承实现Events和Options,UI插件的特征
    Implements: [Events, Options],

    options: {
/*
        //位置改变事件
        onChange: $empty,
        //拖动改变位置完成事件
        onComplete: $empty,
*/
        
// 每一步的事件
        onTick:  function (position)    {
            
// 如果指定吸附,根据步数计算位置
             if ( this .options.snap)    position  =   this .toPosition( this .step);
            
// 设置滑块的位置
             this .knob.setStyle( this .property, position);
        },
        snap: 
false ,
        
// 偏移量
        offset:  0 ,
        
// 指定滑动范围
        range:  false ,
        
// 滚轮支持
        wheel:  false ,
        
// 总步数
        steps:  100 ,
        
// 滑动模式,水平或纵向
        mode:  ' horizontal '
    },

    
// 构造函数,需要三个参数
     // element为滑块所在容器,knob为滑块
    initialize:  function (element, knob, options)    {
        
// 合并参数
         this .setOptions(options);
        
// 取滑块所在的容器对象
         this .element  =  $(element);
        
// 滑块
         this .knob  =  $(knob);
        
// 初始化位置标记变量
         this .previousChange  =   this .previousEnd  =   this .step  =   - 1 ;
        
// 添加鼠标按下的事件监听,实现点击时自动滑到指定位置
         this .element.addEvent( ' mousedown ' this .clickedElement.bind( this ));
        
// 如果设置支持滚轮,为容器添加滚轮监听事件
         if  ( this .options.wheel)     this .element.addEvent( ' mousewheel ' this .scrolledElement.bindWithEvent( this ));
        
// 初始化
         var  offset, limit  =  {}, modifiers  =  { ' x ' false ' y ' false };
        
// 根据不同滑动模式初始化变量值
         switch  ( this .options.mode)    {
            
// 纵向滑动时
             case   ' vertical ' :
                
// 别名为y轴方向
                 this .axis  =   ' y ' ;
                
// 这时主要是需要改变滑块CSS属性中的top
                 this .property  =   ' top ' ;
                
// 此时需要取值的属性为offsetHeiht
                offset  =   ' offsetHeight ' ;
                
break ;
            
// 横向滑动时
             case   ' horizontal ' :
                
// 别名为x轴方向
                 this .axis  =   ' x ' ;
                
// 这时主要是需要改变滑块CSS属性中的left
                 this .property  =   ' left ' ;
                
// 此时需要取值的属性为offsetWidth
                offset  =   ' offsetWidth ' ;
        }
        
// 取滑块在当前滑动方向上的尺寸的一半
         this .half  =   this .knob[offset]  /   2 ;
        
// 计算滑块移动的总距离
         this .full  =   this .element[offset]  -   this .knob[offset]  +  ( this .options.offset  *   2 );
        
// 取范围的下限,默认为0
         this .min  =  $chk( this .options.range[ 0 ])  ?   this .options.range[ 0 ] :  0 ;
        
// 取范围的上限,默认为滑动的总步数
         this .max  =  $chk( this .options.range[ 1 ])  ?   this .options.range[ 1 ] :  this .options.steps;
        
// 计算范围值
         this .range  =   this .max  -   this .min;
        
// 总步数,如果steps参数值为0,则设为滑块移动的总距离
         this .steps  =   this .options.steps  ||   this .full;
        
// 计算每滑动一步的距离
         this .stepSize  =  Math.abs( this .range)  /   this .steps;
        
// 计算每一步所占的宽度(根据上面的等级,这里不如直接用this.stepWidth = this.full/this.steps)
         this .stepWidth  =   this .stepSize  *   this .full  /  Math.abs( this .range) ;

        
// 滑块相对于容器为相对定位
         this .knob.setStyle( ' position ' ' relative ' ).setStyle( this .property,  -   this .options.offset);
        
// 当前方向上对应的属性,转化用于Drag类的参数
        modifiers[ this .axis]  =   this .property;
        
// 滑块的坐标范围
        limit[ this .axis]  =  [ -   this .options.offset,  this .full  -   this .options.offset];
        
// 使滑块可拖动
         this .drag  =   new  Drag( this .knob, {
            snap: 
0 ,
            
// 滑块的可拖动范围
            limit: limit,
            
// 指定拖动的方向及对应属性
            modifiers: modifiers,
            onDrag: 
this .draggedKnob.bind( this ),
            onStart: 
this .draggedKnob.bind( this ),
            onComplete: 
function ()    {
                
this .draggedKnob();
                
this .end();
            }.bind(
this )
        });
        
// 如果指定吸附值
         if  ( this .options.snap)    {
            
// 滑块拖动将网格化,单元格边长为滑动每一步所占的宽度
             this .drag.options.grid  =  Math.ceil( this .stepWidth);
            
// 改变移动范围的上限,此时忽略偏移量
             this .drag.options.limit[ this .axis][ 1 =   this .full;
        }
    },

    
// 设置值
    set:  function (step)    {
        
// 当范围上下限从小到大并且当前步值小于下限,或当范围上下限从大到小并且当前步值大于下限时,设置步值为下限值
         if  ( ! (( this .range  >   0 ^  (step  <   this .min)))    step  =   this .min;
        
// 当范围上下限从小到大并且当前步值大于是限,或当范围上下限从大到小并且当前步值小于上限时,设置步值为上限值
         if  ( ! (( this .range  >   0 ^  (step  >   this .max)))    step  =   this .max;

        
// 计算步数
         this .step  =  Math.round(step);
        
// 检查步数变化,以决定是否触发事件
         this .checkStep();
        
// 结束滑动
         this .end();
        
// 触发步进事件
         this .fireEvent( ' onTick ' this .toPosition( this .step));
        
return   this ;
    },

    
// 点击直接跳到指定位置
    clickedElement:  function (event)    {
        
// 判断方向
         var  dir  =   this .range  <   0   ?   - 1  :  1 ;
        
// 取当前模式下的鼠标在容器内的偏移值
         var  position  =  event.page[ this .axis]  -   this .element.getPosition()[ this .axis]  -   this .half;
        
// 边界处理
        position  =  position.limit( - this .options.offset,  this .full  - this .options.offset);

        
// 计算步数
         this .step  =  Math.round( this .min  +  dir  *   this .toStep(position));
        
// 检查步数变化,以决定是否触发事件
         this .checkStep();
        
// 结束滑动
         this .end();
        
// 触发步进事件
         this .fireEvent( ' onTick ' , position);
    },

    
// 利用滚轮跳到指定位置
    scrolledElement:  function (event)    {
        
// 横向滑动和纵向滑动时,滚轮前滚和后滚导致的滑块的变化方向相反
         var  mode  =  ( this .options.mode  ==   ' horizontal ' ?  (event.wheel  <   0 ) : (event.wheel  >   0 );
        
// mode为真是向小值(左上)滑动,返之向大值(右下)滑动
         this .set(mode  ?   this .step  -   this .stepSize :  this .step  +   this .stepSize);
        
// 阻止事件冒泡及返回值
        event.stop();
    },

    
// 滑块移动时的处理
    draggedKnob:  function ()    {
        
// 判断方向
         var  dir  =   this .range  <   0   ?   - 1  :  1 ;
        
// 取当前模式下的鼠标坐标值
         var  position  =   this .drag.value.now[ this .axis];
        
// 边界处理
        position  =  position.limit( - this .options.offset,  this .full  - this .options.offset);
        
// 计算当前的步数
         this .step  =  Math.round( this .min  +  dir  *   this .toStep(position));
        
// 检查滑动位置有无变化
         this .checkStep();
    },

    
// 检查步数有无变化
    checkStep:  function ()    {
        
// 两值不等说明有改变
         if  ( this .previousChange  !=   this .step)    {
            
// 更新旧值
             this .previousChange  =   this .step;
            
// 触发onChange事件,传送当前步数作参数
             this .fireEvent( ' onChange ' this .step);
        }
    },

    
// 结束滑动,检查步数有无变化
    end:  function ()    {
        
// 两值不等说明有改变
         if  ( this .previousEnd  !==   this .step)    {
            
// 更新旧值
             this .previousEnd  =   this .step;
            
// 触发onComplete事件,传送当前步数作参数
             this .fireEvent( ' onComplete ' this .step  +   '' );
        }
    },

    
// 根据鼠标位置计算当前的步数
    toStep:  function (position)    {
        
var  step  =  (position  +   this .options.offset)  *   this .stepSize  /   this .full  *   this .steps;
        
return   this .options.steps  ?  Math.round(step  -=  step  %   this .stepSize) : step;
    },

    
// 根据当前的步数计算滑块的位置
    toPosition:  function (step)    {
        
return  ( this .full  *  Math.abs( this .min  -  step))  /  ( this .steps  *   this .stepSize)  -   this .options.offset;
    }
});

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值