zoukankan      html  css  js  c++  java
  • 【CSON原创】javascript图片滚动效果发布

    功能说明:

    在GMC实习的时候,写过一个图片滚动切换的控件,现在也发布一下。

    1。支持点击左右按钮滚动图片。

    2。支持点击右上角的选择按钮进行图片滚动。

    支持IE 6 7 8 FireFox Chrome

    效果预览:

     
     

    实现原理:

    把所有对象包含在单行,并且通过按钮的点击,控制单行的移动,实现图片滚动效果。

    通过对数函数实现移动的先加速后减速效果。

    代码分析:

    var defaults = {
    changerId:
    'phos_changer', //控件id
    containerId: 'phos_container', //图片包含块id
    bodyId: 'boxDiv2', //包含块外div的id
    select_btn_Id:'select', //选择按钮前缀
    bodyWidth: 500, //显示区域宽度
    left_btn_Id: 'left_btn', //左按钮id
    right_btn_Id: 'right_btn', //右按钮id
    movePath: 300, //切换速度
    groupCount: 5, //每次显示个数
    btnClass: 'btn', //左右按钮类
    selectorContainerId:'select_btns_area', //选择按钮的容器id
    left_btn_disble_Class: 'left_btn_disable', //左按钮禁用时样式类
    right_btn_disble_Class: 'right_btn_disable', //右按钮禁用时样式类
    select_btn_Class:'select_btn', //选择按钮样式类
    left_btn_Class:'left_btn', //左按钮样式类
    right_btn_Class:'right_btn', //右按钮样式类
    left_btn_over_Class:'left_btn_over', //左按钮鼠标移上去时样式类
    right_btn_over_Class:'right_btn_over', //右按钮鼠标移上去时样式类
    select_btn_selected_Class:'select_btn_selected'//选择按钮被选择后样式类
    };
    var opts=util.extend(defaults,option);

    首先定义默认值对象,里面包含所有参数的默认值,包括左右按钮ID,按钮不同状态下使用的样式class,每次显示对象的数量等,并且下面使用extend把用户传入的参数对象与默认对象结合,形成最终的参数对象,extend写在工具类中,具体如下:

    extend:function(destination,source){
    for(var name in source){
    destination[name]
    =source[name];

    }
    return destination;
    }

    这里由于传入的参数没有引用类型,所以工具类中的extend只实现了浅复制。

    set_EventsHandler_for_selectors:function(obj){
    util.addEventHandler(obj.selectorContainer,
    'click',function(eve){
    eve
    =eve||window.event;
    var target=eve.target||eve.srcElement;
    if(target!=obj.currentSelector){
    var targetIndex=target.id.charAt(target.id.length-1);
    var currentIndex=obj.currentSelector.id.charAt(obj.currentSelector.id.length-1);
    var len=targetIndex-currentIndex;
    if(len>0){
    for(var t=0;t<len;t++){

    len
    >1?obj._moveLeft(obj,obj.movePath+300)():obj._moveLeft(obj)();

    }
    }
    else{
    for(var t=0;t<-len;t++){

    len
    <-1?obj._moveRight(obj,obj.movePath+300)():obj._moveRight(obj)();

    }
    }

    }


    });

    },

    为右上角的选择按钮绑定事件处理程序,当按钮跨度为2(例如有第一个选择按钮跳到第三个选择按钮时),增大滚动速度,原速度(movePath)增加300后传入处理移动的函数。

    _moveLeft:function(obj,movePath) {
    if(!movePath)movePath=obj.movePath;
    returnfunction(){
    if (obj.isLeft) {
    if(obj.selectIndex<obj.selectorArray.length)
    {
    obj.selectorArray[obj.selectIndex].className
    =obj.select_btn_Class;
    obj.selectIndex
    +=1;
    obj.ori_left
    = parseInt(util.getComputedStyle(obj.phos_container).left);
    obj.selectorArray[obj.selectIndex].className
    =obj.select_btn_Class+''+obj.select_btn_selected_Class; }
    obj.currentLeft
    =obj. currentLeft -obj.moveLength;
    obj.isRight
    =false;
    obj._lMove(obj,movePath);

    }
    if (obj.currentLeft <=-(obj.container_length - obj.moveLength)) {

    obj.right_btn.className
    = obj.btnClass+''+obj.right_btn_Class +''+ obj.right_btn_disble_Class;

    obj.isLeft
    =false;
    }
    }

    },

    移动函数有向左移动和向右移动两个,由于两者原理相似,因此这里只分析向左移动函数。这里由于需要向事件处理程序传递参数,所以使用了闭包的方法,返回一个没有参数的function。

    函数首先判断isLeft是否为true,isLeft是控制对象是否能向左滚动的一个属性,当为false时,意味着已经滚动到最后,不能继续滚动,此时不能调用“原子”的向左滚动函数_lMove,该函数如下:

    _lMove:function(obj,movePath) {

    if (parseInt(util.getComputedStyle(obj.phos_container).left) > obj.currentLeft) {

    obj.path
    +=1;

    obj.phos_container.style.left
    =Math.max(obj.currentLeft, obj.ori_left-Math.log(obj.path)/Math.log(5)*movePath) + 'px';
    window.setTimeout(arguments.callee, 50,obj,movePath);
    }
    else {
    obj.path
    =0;

    obj.isRight
    =true;
    obj.left_btn.className
    = obj.btnClass+''+obj.left_btn_Class;
    obj.getCurrentSelector();
    }

    },

    这个就是前面所说的“原子”向左移动的函数,该函数通过定时器递归调用。所谓“原子”,就是每次该函数调用时只向左移动一个单位的位移,该单位的位移使用对数函数计算: 

    单位位移=obj.ori_left-Math.log(obj.path)/Math.log(5)*movePath

    利用对数函数曲线,可以实现先加速后减速的效果。并且需要注意的是由于每次移动固定的位移,所以必须保证移动后的位移小于等于极限的位移,因此需要用Math.max来限定位移量。

    new phos_changer(
    {
    changerId:
    'phos_changer1',
    containerId:
    'phos_container1',
    selectorContainerId:
    'select_btns_area1',
    bodyId:
    'boxDiv1',
    select_btn_Id:
    'select',
    left_btn_Id:
    'left_btn1',
    right_btn_Id:
    'right_btn1'
    });

    最后是调用的方法,传入一个对象,里面包含需要个性化的参数,实现对控件的初始化。

    完整demo代码:

    js: 

    View Code
    var util = {
    $:
    function(sId) { return document.getElementById(sId); },
    addEventHandler:
    function(elem, type, handler) {
    if (elem.addEventListener) {
    elem.addEventListener(type, handler,
    false);
    }
    else {
    elem.attachEvent(
    "on"+ type, handler);
    }
    },
    removeEventHandler:
    function(elem, type, handler) {
    if (elem.removeEventListener) {
    elem.removeEventListener(type, handler,
    false);
    }
    else {
    elem.detachEvent(
    "on"+ type, handler);
    }
    },
    getComputedStyle:
    function(elem) {
    if (elem.currentStyle)
    return elem.currentStyle;
    else {
    return document.defaultView.getComputedStyle(elem, null);
    }
    },

    getElementsByClassName:
    function(className, parentElement) {
    var elems = (parentElement || document.body).getElementsByTagName("*");
    var result = [];
    for (i =0; j = elems[i]; i++) {
    if ((""+ j.className +"").indexOf(""+ className +"") !=-1) {
    result.push(j);
    }
    }
    return result;
    },
    extend:
    function(destination,source){
    for(var name in source){
    destination[name]
    =source[name];

    }
    return destination;
    }


    }

    var _st = window.setTimeout;
    window.setTimeout
    =function(fRef, mDelay) {
    if(typeof fRef =='function'){
    var argu = Array.prototype.slice.call(arguments,2);
    var f = (function(){ fRef.apply(null, argu); });
    return _st(f, mDelay);
    }
    return _st(fRef,mDelay);
    }
    // ]]></script>
    <script type="text/javascript">// <![CDATA[
    var phos_changer =function(option){
    this._init(option);
    }

    phos_changer.prototype
    ={
    _init:
    function(option){

    var defaults = {
    changerId:
    'phos_changer', //控件id
    containerId: 'phos_container', //图片包含块id
    bodyId: 'boxDiv2', //包含块外div的id
    select_btn_Id:'select', //选择按钮前缀
    bodyWidth: 500, //显示区域宽度
    left_btn_Id: 'left_btn', //左按钮id
    right_btn_Id: 'right_btn', //右按钮id
    movePath: 300, //切换速度
    groupCount: 5, //每次显示个数
    btnClass: 'btn', //左右按钮类
    selectorContainerId:'select_btns_area', //选择按钮的容器id
    left_btn_disble_Class: 'left_btn_disable', //左按钮禁用时样式类
    right_btn_disble_Class: 'right_btn_disable', //右按钮禁用时样式类
    select_btn_Class:'select_btn', //选择按钮样式类
    left_btn_Class:'left_btn', //左按钮样式类
    right_btn_Class:'right_btn', //右按钮样式类
    left_btn_over_Class:'left_btn_over', //左按钮鼠标移上去时样式类
    right_btn_over_Class:'right_btn_over', //右按钮鼠标移上去时样式类
    select_btn_selected_Class:'select_btn_selected'//选择按钮被选择后样式类
    };
    var opts=util.extend(defaults,option);


    this.phos_changer = util.$(opts.changerId);
    this.phos_container = util.$(opts.containerId);
    this.phos_body = util.$(opts.bodyId);
    this.left_btn = util.$(opts.left_btn_Id);
    this.right_btn = util.$(opts.right_btn_Id);
    this.selectorContainer=util.$(opts.selectorContainerId);
    this.select_btn_Class=opts.select_btn_Class;
    this.selectorArray= util.getElementsByClassName(this.select_btn_Class,this.selectorContainer);
    this.ori_left=this.currentLeft = parseInt(util.getComputedStyle(this.phos_container).left);
    this.memberWidth =(this.phos_container.getElementsByTagName('li')[0]).clientWidth;
    this.count =this.phos_container.getElementsByTagName('li').length;
    this.isLeft =true;
    this.isRight =false;
    this.selectIndex=0;
    this.movePath=opts.movePath;
    this.select_btn_Id=opts.select_btn_Id;
    this.groupCount;
    this.btnClass=opts.btnClass;
    this.left_btn_disble_Class=opts.left_btn_disble_Class;
    this.right_btn_disble_Class=opts.right_btn_disble_Class;
    this.left_btn.className = opts.btnClass +''+opts.left_btn_Class+''+ opts.left_btn_disble_Class;
    this.left_btn_Class=opts.left_btn_Class;
    this.right_btn_Class=opts.right_btn_Class;
    this.left_btn_over_Class=opts.left_btn_over_Class;
    this.right_btn_over_Class=opts.right_btn_over_Class;
    this.select_btn_selected_Class=opts.select_btn_selected_Class;
    this.path=0;

    this.selectorArray[0].className=this.select_btn_Class+''+this.select_btn_selected_Class;

    this.phos_body.style.width = opts.bodyWidth +'px';
    this.groupCount =opts.groupCount;

    this.moveLength =this.memberWidth *this.groupCount;
    this.phos_body.style.width =this.moveLength +'px';

    this.container_length =this. memberWidth *this. count;
    this.phos_container.style.width =this.container_length +'px';

    util.addEventHandler(
    this.left_btn, 'click', this._moveRight(this));
    util.addEventHandler(
    this.right_btn, 'click', this._moveLeft(this));
    this.getCurrentSelector();
    this.set_EventsHandler_for_selectors(this);
    this._setBtnState();




    },
    /* 为选择按钮设置事件处理程序 */
    set_EventsHandler_for_selectors:
    function(obj){
    util.addEventHandler(obj.selectorContainer,
    'click',function(eve){
    eve
    =eve||window.event;
    var target=eve.target||eve.srcElement;
    if(target!=obj.currentSelector){
    var targetIndex=target.id.charAt(target.id.length-1);
    var currentIndex=obj.currentSelector.id.charAt(obj.currentSelector.id.length-1);
    var len=targetIndex-currentIndex;
    if(len>0){
    for(var t=0;t<len;t++){

    len
    >1?obj._moveLeft(obj,obj.movePath+300)():obj._moveLeft(obj)();//跨度大的切换提高切换速度

    }
    }
    else{
    for(var t=0;t<-len;t++){

    len
    <-1?obj._moveRight(obj,obj.movePath+300)():obj._moveRight(obj)();

    }
    }

    }


    });

    },
    /* 获得当前被选择的选择按钮 */
    getCurrentSelector:
    function(){
    for(var i=0;i<this.selectorArray.length;i++){
    if( this.selectorArray[i].className==this.select_btn_Class+''+this.select_btn_selected_Class){

    this.currentSelector=this.selectorArray[i];
    break;
    }

    }

    },
    /* 左移动原子方法 */
    _lMove:
    function(obj,movePath) {

    if (parseInt(util.getComputedStyle(obj.phos_container).left) > obj.currentLeft) {

    obj.path
    +=1;

    obj.phos_container.style.left
    = Math.max(obj.currentLeft, obj.ori_left - Math.log(obj.path) / Math.log(5) * movePath) +'px'; //对数函数实现先加速再减速效果
    window.setTimeout(arguments.callee, 50,obj,movePath);
    }
    else {
    obj.path
    =0;

    obj.isRight
    =true;
    obj.left_btn.className
    = obj.btnClass+''+obj.left_btn_Class;
    obj.getCurrentSelector();
    }

    },

    /* 右移动原子方法 */
    _rMove:
    function(obj,movePath) {
    if (parseInt(util.getComputedStyle(obj.phos_container).left) < obj.currentLeft) {
    obj.path
    +=1;

    obj.phos_container.style.left
    =Math.min(obj.currentLeft,obj.ori_left + Math.log(obj.path)/Math.log(5)*movePath )+ 'px';//对数函数实现先加速再减速效果
    window.setTimeout(arguments.callee, 50,obj,movePath);
    }
    else {
    obj.path
    =0;
    obj.isLeft
    =true;
    obj.right_btn.className
    = obj.btnClass+''+obj.right_btn_Class;
    obj.getCurrentSelector();

    }

    },
    /* 左移动方法 */
    _moveLeft:
    function(obj,movePath) {
    if(!movePath)movePath=obj.movePath;
    returnfunction(){
    if (obj.isLeft) {
    if(obj.selectIndex<obj.selectorArray.length)
    {
    obj.selectorArray[obj.selectIndex].className
    =obj.select_btn_Class;
    obj.selectIndex
    +=1;
    obj.ori_left
    = parseInt(util.getComputedStyle(obj.phos_container).left);
    obj.selectorArray[obj.selectIndex].className
    =obj.select_btn_Class+''+obj.select_btn_selected_Class; }
    obj.currentLeft
    =obj. currentLeft -obj.moveLength;
    obj.isRight
    =false;
    obj._lMove(obj,movePath);

    }
    if (obj.currentLeft <=-(obj.container_length - obj.moveLength)) {

    obj.right_btn.className
    = obj.btnClass+''+obj.right_btn_Class +''+ obj.right_btn_disble_Class;

    obj.isLeft
    =false;
    }
    }

    },
    /* 右移动方法 */
    _moveRight:
    function(obj,movePath) {
    if(!movePath)movePath=obj.movePath;
    returnfunction(){
    if (obj.isRight) {

    if(obj.selectIndex>0)
    {
    obj.selectorArray[obj.selectIndex].className
    =obj.select_btn_Class;
    obj.selectIndex
    -=1;
    obj.selectorArray[obj.selectIndex].className
    =obj.select_btn_Class+''+obj.select_btn_selected_Class; }

    obj.currentLeft
    = obj.currentLeft + obj.moveLength;
    obj.ori_left
    = parseInt(util.getComputedStyle(obj.phos_container).left);
    obj.isLeft
    =false;
    obj._rMove(obj,movePath);


    }
    if ( obj.currentLeft >=0) {

    obj.left_btn.className
    = obj.btnClass +''+obj.left_btn_Class +''+obj.left_btn_disble_Class;
    obj.isRight
    =false;
    }
    }
    },
    /* 改变鼠标移上按钮时按钮状态 */
    _overStateChange:
    function(btn,obj,dir){

    returnfunction(){
    var className;
    dir
    =='left'?className=obj.left_btn_Class+''+obj.left_btn_over_Class:className=obj.right_btn_Class+''+obj.right_btn_over_Class;
    btn.className
    =obj.btnClass+''+className;

    }


    },
    /* 设置按钮的手型效果 */
    _setBtnState:
    function(){

    for(var i=0;i<this.selectorArray.length;i++){
    this.selectorArray[i].style.cursor='pointer';

    }
    this.left_btn.style.cursor=this.right_btn.style.cursor='pointer';


    }












    }
    /* 初始化调用 */
    new phos_changer(
    {
    changerId:
    'phos_changer1',
    containerId:
    'phos_container1',
    selectorContainerId:
    'select_btns_area1',
    bodyId:
    'boxDiv1',
    select_btn_Id:
    'select',
    left_btn_Id:
    'left_btn1',
    right_btn_Id:
    'right_btn1'
    });

    CSS:

    View Code
    *{margin:0; padding:0}
    .phos_changer
    {width:650px; position:relative; height:200px;}
    .productCol
    { overflow:hidden;height:100px; width:500px; position:absolute; left:50%; margin-left:-250px; top:30px;}
    .phos_container
    {height:100%; position:absolute; left:0; top:0;}
    .btn
    {width:45px; height:45px; position:absolute;}
    .left_btn
    { left:20px; top:60px; z-index:100; background-image:url(http://images.cnblogs.com/cnblogs_com/Cson/290336/r_left-btn-over.png); background-repeat:no-repeat;}
    .right_btn
    { right:20px; top:60px; z-index:100; background-image:url(http://images.cnblogs.com/cnblogs_com/Cson/290336/r_right-btn-over.png); background-repeat:no-repeat;}
    .left_btn_over
    {background-image:url(http://images.cnblogs.com/cnblogs_com/Cson/290336/r_left-btn-over.png);}
    .right_btn_over
    {background-image:url(http://images.cnblogs.com/cnblogs_com/Cson/290336/r_right-btn-over.png);}
    .left_btn_disable
    {background-image:url(http://images.cnblogs.com/cnblogs_com/Cson/290336/r_left-btn.png);}
    .right_btn_disable
    {background-image:url(http://images.cnblogs.com/cnblogs_com/Cson/290336/r_right-btn.png);}

    .select_btns_area
    {position:absolute; top:0; right:50px;}
    .select_btn
    {width:15px; height:15px; background-image:url(http://images.cnblogs.com/cnblogs_com/Cson/290336/r_pageBtn-up.png); background-repeat:no-repeat; float:left; margin-left:10px; display:inline;}

    .select_btn_selected
    {background-image:url(http://images.cnblogs.com/cnblogs_com/Cson/290336/r_pageBtn-select.png); background-repeat:no-repeat;}
    .photo_container
    { width:100px; height:100px; background-color:Red; float:left;}

    HTML:

    View Code
    <ul id="phos_changer1" class="phos_changer" style="list-style: none;">
    <div id="select_btns_area1" class="select_btns_area">
    <div id="select0" class="select_btn"></div>
    <div id="select1" class="select_btn"></div>
    <div id="select2" class="select_btn"></div>
    </div>
    <div id="left_btn1" class="btn left_btn"></div>
    <div id="boxDiv1" class="productCol">
    <div id="phos_container1" class="phos_container">
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_z.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_3.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_2a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_3a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_4a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_5a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_6a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_7a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_8a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_9a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_10a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_12a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_13a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_14a.jpg" style=" 100%; height: 100%;"/></li>
    <li class="photo_container"><img src="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_15a.jpg" style=" 100%; height: 100%;"/></li>
    </div>
    </div>
    <div id="right_btn1" class="btn right_btn"></div>
    </ul>

      

    欢迎转载,请标明出处:http://www.cnblogs.com/Cson/archive/2011/03/30/2000075.html#

  • 相关阅读:
    51nod1432 独木舟
    51nod1126 求递推序列的第N项
    Alice, Bob, Oranges and Apples CodeForces
    区间dp
    平面几何基础
    图的割点、桥与双连通分支
    hihocoder 1305 区间求差
    hdu 2444 The Accomodation of Students 【二分图匹配】
    状压dp
    hdu 1525 Euclid's Game【 博弈论】
  • 原文地址:https://www.cnblogs.com/Cson/p/2000075.html
Copyright © 2011-2022 走看看