cloudgamer
你的真诚让我心动, 你的柔情让我不懂, 你的宽容让我感动, 你的爱我会永远珍藏.
随笔- 50  文章- 15  评论- 403 
博客园  首页  新随笔    管理  订阅 订阅

JavaScript 图片切换展示效果

看到alibaba的一个图片切换效果,感觉不错,想拿来用用。但代码一大堆的,看着昏,还是自己来吧。

由于有了做图片滑动展示效果的经验,做这个就容易得多了。

先看看效果:

根据alibaba做的效果:
  • 1
  • 2
  • 3
alibaba的按钮有一个延迟的功能,应该加个定时器,但这个不是重点就省了吧。

扩展成能左右切换:
  • 1
  • 2
  • 3

其他扩展功能:





切换速度:

停顿时间:


程序说明:
首先需要一个容器,设置它的overflow为hidden,position为relative;
容器里面还要一个滑动对象,设置它的position为
absolute;
在initialize()函数里初始化一些属性。

在切换之前先执行Start()函数,进行相关设置,
主要是设置Index属性(索引)和_target属性(目标值):
Code
if(this.Index < 0){
    
this.Index = this._count - 1;
} 
else if  (this.Index >= this._count){ this.Index = 0; }

this._target = -1 * this._parameter * this.Index;

接着就执行Move()函数开始移动了,原理通过设置滑动对象的top(或left)来做出移动的效果,
而减速的效果就需要执行GetStep()函数来获取步长:
var iStep = (iTarget - iNow) / this.Step;
用目标值减当前值再除以一个参数,得到步长,
这样取得的步长在当前值越接近目标值时会越来越小,也做成了减速的效果,
然后在top(或left)的设置中加上这个步长,并设置定时器继续Move(),直到到达目标值:
Code
this._slider.style[style] = (iNow + iStep) + "px";
this._timer = setTimeout(function(){ oThis.Move(); }, this.Time);

下面例子里的容器结构:
Code
<div class="container" id="idTransformView">
  
<ul class="slider" id="idSlider">
    
<li><img src="http://shundebk.cn/temp/1.jpg"/></li>
    
<li><img src="http://shundebk.cn/temp/2.jpg"/></li>
    
<li><img src="http://shundebk.cn/temp/3.gif"/></li>
  
</ul>
  
<ul class="num" id="idNum">
    
<li>1</li>
    
<li>2</li>
    
<li>3</li>
  
</ul>
</div>

要美观的话需要css设置一下:
Code
.container, .container *{margin:0; padding:0;}

.container
{width:408px; height:168px; overflow:hidden;}

.slider
{position:absolute;}
.slider li
{ list-style:none;display:inline;}
.slider img
{ width:408px; height:168px; display:block;}

.slider2
{width:2000px;}
.slider2 li
{float:left;}

.num
{ position:absolute; right:5px; bottom:5px;}
.num li
{
    float
: left;
    color
: #FF7300;
    text-align
: center;
    line-height
: 16px;
    width
: 16px;
    height
: 16px;
    font-family
: Arial;
    font-size
: 12px;
    cursor
: pointer;
    overflow
: hidden;
    margin
: 3px 1px;
    border
: 1px solid #FF7300;
    background-color
: #fff;
}
.num li.on
{
    color
: #fff;
    line-height
: 21px;
    width
: 21px;
    height
: 21px;
    font-size
: 16px;
    margin
: 0 1px;
    border
: 0;
    background-color
: #FF7300;
    font-weight
: bold;
}
样式的设置跟程序也有一定关系,例如宽和高,这里就不说明了。

接着就可以实例化了:
Code
var tv = new TransformView ("idTransformView", "idSlider", 168, 3, {
    onStart : function(){ Each(objs, function(o, i) { o.className = tv.Index == i ? "on" : ""; })  }//按钮样式
});
这里主要有4个参数,分别是容器对象、滑动对象、切换参数和切换数量。
当程序是上下切换时,切换参数切换的高度,当左右切换时,是切换的宽度。
切换数量就是有多少个切换对象了,例如上面的例子就是3个。
最后的参数是一些设置:
属性: 默认值//说明
Up:   true,//是否向上(否则向左)
Step:  5,//滑动变化率
Time:  10,//滑动延时
Auto:  true,//是否自动转换
Pause:  2000,//停顿时间(Auto为true时有效)
onStart: function(){},//开始转换时执行
onFinish: function(){}//完成转换时执行

例子里设置了onStart属性,作用是在切换开始时,设置按钮的样式

例子里完整的测试代码:
Code
function Each(list, fun){
    
for (var i = 0, len = list.length; i < len; i++) { fun(list[i], i); }
};

var objs = $("idNum").getElementsByTagName("li");

var tv = new TransformView("idTransformView", "idSlider", 168, 3,  {
    onStart : 
function(){ Each(objs, function(o, i) { o.className = tv.Index == i ? "on" : ""; }) }//按钮样式
});

tv.Start();

Each(objs, 
function (o, i){
    o.onmouseover 
= function(){
        o.className 
= "on";
        tv.Auto 
= false;
        tv.Index 
= i;
        tv.Start();
    }
    o.onmouseout 
= function(){
        o.className 
= "";
        tv.Auto 
= true;
        tv.Start();
    }
})

源码:
Code
var $ = function (id) {
    
return "string" == typeof id ? document.getElementById(id) : id;
};

var Class = {
  create: 
function() {
    
return function() {
      
this.initialize.apply(this, arguments);
    }
  }
}

Object.extend 
= function(destination, source) {
    
for (var property in source) {
        destination[property] 
= source[property];
    }
    
return destination;
}

var TransformView = Class.create();
TransformView.prototype 
= {
  
//容器对象,滑动对象,切换参数,切换数量
  initialize: function(container, slider, parameter, count, options) {
    
if(parameter <= 0 || count <= 0) return;
    
var oContainer = $(container), oSlider = $(slider), oThis = this;

    
this.Index = 0;//当前索引
    
    
this._timer = null;//定时器
    this._slider = oSlider;//滑动对象
    this._parameter = parameter;//切换参数
    this._count = count || 0;//切换数量
    this._target = 0;//目标参数
    
    
this.SetOptions(options);
    
    
this.Up = !!this.options.Up;
    
this.Step = Math.abs(this.options.Step);
    
this.Time = Math.abs(this.options.Time);
    
this.Auto = !!this.options.Auto;
    
this.Pause = Math.abs(this.options.Pause);
    
this.onStart = this.options.onStart;
    
this.onFinish = this.options.onFinish;
    
    oContainer.style.overflow 
= "hidden";
    oContainer.style.position 
= "relative";
    
    oSlider.style.position 
= "absolute";
    oSlider.style.top 
= oSlider.style.left = 0;
  },
  
//设置默认属性
  SetOptions: function(options) {
    
this.options = {//默认值
        Up:            true,//是否向上(否则向左)
        Step:        5,//滑动变化率
        Time:        10,//滑动延时
        Auto:        true,//是否自动转换
        Pause:        2000,//停顿时间(Auto为true时有效)
        onStart:    function(){},//开始转换时执行
        onFinish:    function(){}//完成转换时执行
    };
    Object.extend(
this.options, options || {});
  },
  
//开始切换设置
  Start: function() {
    
if(this.Index < 0){
        
this.Index = this._count - 1;
    } 
else if (this.Index >= this._count){ this.Index = 0; }
    
    
this._target = -1 * this._parameter * this.Index;
    
this.onStart();
    
this.Move();
  },
  
//移动
  Move: function() {
    clearTimeout(
this._timer);
    
var oThis = this, style = this.Up ? "top" : "left", iNow = parseInt(this._slider.style[style]) || 0, iStep = this.GetStep(this._target, iNow);
    
    
if (iStep != 0) {
        
this._slider.style[style] = (iNow + iStep) + "px";
        
this._timer = setTimeout(function(){ oThis.Move(); }, this.Time);
    } 
else {
        
this._slider.style[style] = this._target + "px";
        
this.onFinish();
        
if (this.Auto) { this._timer = setTimeout(function(){ oThis.Index++; oThis.Start(); }, this.Pause); }
    }
  },
  
//获取步长
  GetStep: function(iTarget, iNow) {
    
var iStep = (iTarget - iNow) / this.Step;
    
if (iStep == 0) return 0;
    
if (Math.abs(iStep) < 1) return (iStep > 0 ? 1 : -1);
    
return iStep;
  },
  
//停止
  Stop: function(iTarget, iNow) {
    clearTimeout(
this._timer);
    
this._slider.style[this.Up ? "top" : "left"] = this._target + "px";
  }
};

下载测试代码
Tag标签: 图片,切换,JavaScript
posted @ 2008-07-06 01:25 cloudgamer 阅读(5337) 评论(48)  编辑 收藏 所属分类: Javascript
发表评论
  回复  引用  查看    
2008-07-06 02:08 | Bēniaǒ      
不错,学习了。
  回复  引用  查看    
2008-07-06 02:16 | cloudgamer      
@Bēniaǒ
这么快
谢谢
  回复  引用    
2008-07-06 07:18 | wuya2 [未注册用户]
写得很清楚,谢谢。

很久以前到YESKY偷了一个做类似效果的js文件,没看懂,只会用 -_-
  回复  引用    
2008-07-06 07:45 | jillzhang(未登陆的) [未注册用户]
写得非常帅,收藏啦
  回复  引用  查看    
2008-07-06 07:52 | 生鱼片      
我也收藏,说不定什么时候可以用到
  回复  引用  查看    
2008-07-06 08:43 | DQW      
收藏了,谢谢
  回复  引用    
2008-07-06 09:22 | 庞永庆 [未注册用户]
你好 我是出版社的编辑,我看到你博客中的内容,感觉写的非常好。现在要出版一本JavaScript的书,如果想把这些内容和更多的人分享,可以和我联系,把这些东西写成书。
我的邮箱:books_522008@yahoo.com.cn
  回复  引用  查看    
2008-07-06 09:47 | 真见      
哇,厉害。。写出来又是按钮地,又是效果地,花地功夫不少啊,我真是跟你不能比。。
  回复  引用    
2008-07-06 11:07 | 上帝书城 [未注册用户]
在Firefox下好像有点问题
  回复  引用  查看    
2008-07-06 11:41 | Hawker      
@上帝书城

--引用--------------------------------------------------
上帝书城: 在Firefox下好像有点问题 --------------------------------------------------------
修改两处:var oContainer和var objs为
var oContainer = $("idtransformview"), oSlider = $("idslider")
var objs = $("idnum").getElementsByTagName("li");
在ff3下调试通过
  回复  引用  查看    
2008-07-06 14:24 | cloudgamer      
@wuya2
@jillzhang(未登陆的)
@生鱼片
@DQW
@真见
谢谢

@上帝书城
我在ff2下好像没什么问题
能具体说说么
  回复  引用  查看    
2008-07-06 14:39 | cloudgamer      
@庞永庆
呵呵
可以啊
能记上我的大名就最好了^_^
  回复  引用  查看    
2008-07-06 15:45 | Bēniaǒ      
@cloudgamer
呵呵,慢了就没SF可坐了。当然得快点。
  回复  引用  查看    
2008-07-07 00:52 | BAsil      
我刚发过一个js的图片幻灯,不过根本没法和你的比,你这个太棒了
另外我发现你的代码中引用了prototype的部分代码,不知道jquery中是否有类似的代码,对jquery没有了解,希望能和楼主多交流
  回复  引用  查看    
2008-07-07 01:55 | 狼Robot      
学习
  回复  引用  查看    
2008-07-07 08:20 | cloudgamer      
@BAsil
jquery我也不懂,只是之前研究过一阵子prototype感觉它的类结构很不错就拿来用了
  回复  引用  查看    
2008-07-07 08:34 | shenjk      
只说一个字:帅
  回复  引用  查看    
2008-07-07 09:43 | Leem      
帅的掉渣,jquery应该也有类似的插件.
  回复  引用  查看    
2008-07-07 09:46 | 我太有才了      
.......不好意思。
我这边用上去显示出了问题
可不可以把源代码发我邮箱让我学习学习。。
谢谢啊。
  回复  引用    
2008-07-07 11:11 | 林 [未注册用户]
这个用的是绝对定位,
使用时会不会对页面排版有问题,就是说会不会因为浏览器的不同,分辩率的不同而造成这东东移位呢?
  回复  引用  查看    
2008-07-07 11:38 | cloudgamer      
@林
应该不会
因为容器并没有绝对定位
里面的内容也只是相对定位
  回复  引用  查看    
2008-07-07 11:40 | cloudgamer      
@Leem
@shenjk
谢谢

@我太有才了
你可以复制页面的源码
  回复  引用    
2008-07-08 09:04 | 张刚 [未注册用户]
function Each(list, fun){
for (var i = 0, len = list.length; i < len; i++) { fun(list[i], i); }
};

作者你好。上边这个语句中的。参数list是不是要把页面中的所有li都统计了。能不能只统计一部分呀?(我用了这个语句后。别的javascript功能就不能用了)
  回复  引用  查看    
2008-07-08 10:01 | BAsil      
@张刚
能再具体描述一下吗?
  回复  引用  查看    
2008-07-08 10:53 | cloudgamer      
@张刚
应该不会这样
因为$("idNum").getElementsByTagName("li");
取的是idNum里面的li
跟其他li是没有关系的
  回复  引用    
2008-07-09 09:10 | 张刚 [未注册用户]
我是在一个页里调用了两个js文件,如果把你上边本文的这个js文件放到另一个的前边,另一个的功能就好使了。
(我也没有找出原因来,
cloudgamer说的“因为$("idNum").getElementsByTagName("li");
取的是idNum里面的li ”
我也看到了这句,但还是有问题,最后就把这个js文件放到前边了)

  回复  引用  查看    
2008-07-09 10:25 | cloudgamer      
@张刚
那可能跟另一个js有关
例如同名之类的
  回复  引用    
2008-07-10 14:06 | 张刚 [未注册用户]
“JavaScript 无缝上下(左右)滚动加定高(定宽)停顿效果” 和“JavaScript 图片切换展示效果 ”,我把这两个的js文件分别单独放到两个js文件里,这两种js效果要在一个页里同时实现,在页中同时引用这两个js文件后,只能有一个效果出现,另一个不能实现。(我发现可能是有两个windows.onload的,想把两个windows.onload单独写在一个js文件里成一个windows.onload,但“JavaScript 无缝上下(左右)滚动加定高(定宽)停顿效果”这个是能实现,“图片切换展示效果”就不能实现)如何解决?
  回复  引用  查看    
2008-07-10 20:20 | cloudgamer      
@张刚
这两个好像没什么冲突的啊
最好你给你那页面我看看
  回复  引用  查看    
2008-08-01 15:46 | 阿一(杨正祎)      
一个字——太帅了~~!
  回复  引用  查看    
2008-08-03 18:42 | cloudgamer      
@阿一(杨正祎)
谢谢
  回复  引用    
2008-08-19 23:54 | 刘谢 [未注册用户]
学习ing
  回复  引用    
2008-08-22 13:23 | Nicky03 [未注册用户]
LZ....很羡慕你的JS技术的。

有个问题一直想问你的。。

我刚学JS.。。书也看了2本了。自己也会学着做一些简单的JS特效。

为什么我看你写的代码还看不懂呢。。

这就挺郁闷的。。就像这样的var $ = function (id) {
return "string" == typeof id ? document.getElementById(id) : id;
};

var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}

Object.extend = function(destination, source) {
for (var property in source) {
destination[property] = source[property];
}
return destination;
}




有的代码好像JS书上都没出现过吧。。。

你也没用Jquery 框架。。看的我挺没信心的。。

麻烦你给提下建议。。谢谢了。。
  回复  引用  查看    
2008-08-22 13:52 | cloudgamer      
@刘谢
谢谢

@Nicky03
不知你学了js多久
我觉得一开始学js只要多看多写明白一些技巧慢慢就觉得有些窍门
理解到一定程度再看书来打好基础就好了
  回复  引用    
2008-08-23 16:23 | Nicky03 [未注册用户]
谢谢你的回复。。

我学JS有一个多月了吧。。

一般的JS特效我还能做出来的。

想这样的JS特效我怎么看你的代码都看不明白。

真的很没信心。。好受打击。
  回复  引用    
2008-08-23 16:24 | Nicky03 [未注册用户]
有没有这方面的详细讲解啊。谢谢了。
  回复  引用    
2008-08-23 17:17 | Nicky03 [未注册用户]
this.Index = 0;//当前索引

在整个JS中起到什么作用。麻烦告诉下。
  回复  引用  查看    
2008-08-23 22:20 | cloudgamer      
@Nicky03
初学的话还是多练练吧
做的多了才能理解js的面向对象 作用域 闭包和函数式编程等等更难的东西

this.Index就是要显示的对象的索引值咯
  回复  引用    
2008-08-27 11:37 | aaaaa [未注册用户]
我觉得楼主应该写一个系列的教程
这样放这些效果 实际用处其实不大
授人以鱼 不如...
  回复  引用  查看    
2008-08-27 13:49 | cloudgamer      
@aaaaa
我不是写了程序说明了吗
那些就相当于教程了
至于实际用处,我想关键是掌握这里面的一些技巧
那就能做到随心所欲了
  回复  引用  查看    
2008-08-28 10:53 | 想爱就去爱吧      
收藏了啊
  回复  引用  查看    
2008-08-28 21:55 | cloudgamer      
@想爱就去爱吧
谢谢
  回复  引用    
2008-09-25 16:41 | 珍仪 [未注册用户]
在网上找了这么久,就你这个最好用。厉害呀!惭愧啊!
  回复  引用  查看    
2008-09-25 20:48 | cloudgamer      
@珍仪
谢谢支持
  回复  引用    
2008-09-26 20:17 | mgd21 [未注册用户]
先感谢你给我的回答,是我没有说明白,我要的是跟这个是一样的http://www.hegsbjz.cn/
我的单位性质跟这个是一样的\
可以吗?
  回复  引用  查看    
2008-09-26 23:48 | cloudgamer      
@mgd21
那个是flash哦
或者用这个
http://www.cnblogs.com/cloudgamer/archive/2008/05/23/1205642.html
  回复  引用  查看    
2008-10-05 18:29 | mike108mvp      
请问如如果要展示5个图片,在哪里设置参数?
  回复  引用  查看    
2008-10-05 20:08 | cloudgamer      
@mike108mvp
"这里主要有4个参数,分别是容器对象、滑动对象、切换参数和切换数量"
你把切换参数设为5就行