【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;
return function (){
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;
return function (){
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;
return function (){
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){

return function (){
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 ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_3.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_2a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_3a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_4a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_5a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_6a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_7a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_8a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_9a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_10a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_12a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_13a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_14a.jpg" style ="width: 100%; height: 100%;" /></ li >
< li class ="photo_container" >< img src ="http://images.cnblogs.com/cnblogs_com/Cson/290336/r_15a.jpg" style ="width: 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#

转载于:https://www.cnblogs.com/Cson/archive/2011/03/30/2000075.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值