一个优化后的JS图片轮播,2011.09.29修正

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
.wy_img_scroll{ position:relative; overflow:hidden;}
	.wy_img_scroll a{ text-decoration:none; font-size:12px; color:#000;}
	.wy_img_scroll img{ vertical-align:middle; border:none;}
	.wy_img_scroll ul{ list-style:none; margin:0; padding:0; position:absolute; left:0; top:0; overflow:hidden; zoom:1;}
		.wy_img_scroll li{ float:left;}
	.wy_img_scroll .guide{ position:absolute; right:5px; bottom:5px; overflow:hidden; zoom:1;}
		.wy_img_scroll .guide a{ display:block; float:left; margin:0 1px; text-align:center; width:20px; height:20px; line-height:20px; background:#FFF; border:#4F2E06 1px solid;}
			.wy_img_scroll .guide a.hover{ background:#EA8B14; color:#FFF; font-weight:bold;}
</style>
</head>
<body>
<div class="wy_img_scroll" id="wy_img_scroll"></div>
<script type="text/javascript">// JS代码在下面
</script>
</body>
</html>

 

function wy_img_scroll(a,b){
	var _=this;
	_.dom = document.getElementById(a);
	_.data = b;
	_.pic_data = b.pic;
	_.scroll_type = b.scroll_type == 2 ? 2 : 1;
	_.auto_time = b.time ? b.time : 5;
}
wy_img_scroll.prototype.check_in_dom = function(a,b){ // 检查a是不是在b之中
	var _=this;
	if (a==b) return true;
	else if (!a.parentNode) return false;
	else if (a.parentNode==b) return true;
	else return _.check_in_dom(a.parentNode, b);
};
wy_img_scroll.prototype.init = function(){ // 获取数据写DOM,绑事件
	var _=this, arr_1=[], arr_2=[], str = "";
	// 写HTML
	_.dom.style.width = _.data.width+"px";
	_.dom.style.height = _.data.height+"px";
	for (var i=0, I=_.pic_data.length; i<I; i++){
		arr_1.push('<li><a href="'+_.pic_data[i]["link"]+'" target="_blank" title="'+_.pic_data[i]["title"]+'"><img src="'+_.pic_data[i]["src"]+'" style="width:'+_.data.width+'px; height:'+_.data.height+'px;" /></a></li>');
		arr_2.push('<a href="javascript:void(0);" οnclick="return false;" title="'+_.pic_data[i]["title"]+'" guide_flag="'+i+'">'+(i+1)+'</a>');
	}
	str = '<ul>'+arr_1.join("")+'</ul><span class="guide">'+arr_2.join("")+'</span>';
	_.dom.innerHTML = str;
	_.ul = _.dom.getElementsByTagName("ul")[0];
	_.guide_list = _.dom.getElementsByTagName("span")[0].getElementsByTagName("a");
	_.ul.style.width = (_.scroll_type==1?_.data.width:_.data.width*_.pic_data.length)+"px";
	// 绑事件
	if (window.attachEvent){
		_.dom.attachEvent("onmouseover", function(){_.mouseover();});
		_.dom.attachEvent("onmouseout", function(){_.mouseout();});
	}else {
		_.dom.addEventListener("mouseover", function(e){_.mouseover(e);}, false);
		_.dom.addEventListener("mouseout", function(e){_.mouseout(e);}, false);
	}
	_.move_to(0);
	_.start_auto();
};
wy_img_scroll.prototype.move_to = function(n){ // 移动至第n张图
	var _=this;
	_.now_show = n;
	for (var i=0, I=_.pic_data.length; i<I; i++) _.guide_list[i].className = i == n ? "hover" : "";
	_.timer_move && window.clearInterval(_.timer_move);
	_.timer_move = window.setInterval(function(){
		if (_.scroll_type == 1){ // 上下
			var final = 0 - n*_.data.height;
			if (_.ul.offsetTop != final){
				var newoffset = (final - _.ul.offsetTop) / 3 + _.ul.offsetTop;
				newoffset = Math.abs(final-newoffset) < 2 ? final : newoffset;
				_.ul.style.top = newoffset+"px";
			}else _.timer_move && window.clearInterval(_.timer_move);
		}else { // 左右
			var final = 0 - n*_.data.width;
			if (_.ul.offsetLeft != final){
				var newoffset = (final - _.ul.offsetLeft) / 3 + _.ul.offsetLeft;
				newoffset = Math.abs(final-newoffset) < 2 ? final : newoffset;
				_.ul.style.left = newoffset+"px";
			}else _.timer_move && window.clearInterval(_.timer_move);
		}
	}, 15);
};
wy_img_scroll.prototype.stop_auto = function(){ // 停止自动滚动
	var _=this;
	_.timer_auto && window.clearInterval(_.timer_auto);
};
wy_img_scroll.prototype.start_auto = function(){ // 开始自动滚动
	var _=this;
	_.timer_auto = window.setInterval(function(){ _.auto();}, _.auto_time*1000);
};
wy_img_scroll.prototype.auto = function(){ // 自动运动事件
	var _=this, n=_.now_show>=_.pic_data.length-1?0:_.now_show+1;
	_.move_to(n);
};
wy_img_scroll.prototype.mouseover = function(){ // 鼠标滑过事件
	var _=this, e=arguments[0]||window.event, obj=e.target||e.srcElement;
	_.stop_auto();
	if (obj.getAttribute("guide_flag")) _.move_to(obj.getAttribute("guide_flag"));
};
wy_img_scroll.prototype.mouseout = function(){ // 鼠标移出事件
	var _=this, e=arguments[0]||window.event, obj=e.relatedTarget||e.toElement;
	if (!_.check_in_dom(obj, _.dom)) _.start_auto();
};
var data = {
	"time":5,
	"width":960,
	"height":250,
	"scroll_type":2,
	"pic":[
		{"src":"http://att.gamefy.cn/201109/att131530177022291.jpg","link":"about:blank","title":"test_1"},
		{"src":"http://att.gamefy.cn/201109/att131521759534930.jpg","link":"about:blank","title":"test_2"},
		{"src":"http://att.gamefy.cn/201108/att131423785570729.jpg","link":"about:blank","title":"test_3"},
		{"src":"http://att.gamefy.cn/201109/att131529721811688.jpg","link":"about:blank","title":"test_4"},
		{"src":"http://att.gamefy.cn/201109/att131486100691248.jpg","link":"about:blank","title":"test_5"}
	]
};
var img_scroller = new wy_img_scroll("wy_img_scroll", data);
img_scroller.init();


 

 

 


 不再给每个元素绑定事件了,只给整个轮播的DIV绑定onmouseover和onmouseout事件……其它的通过判断鼠标所滑过的元素

 

2011.09.29日发现出现问题。

问题一、鼠标滑动按钮后,再令其继续自动滚动可能出现白屏。

经查,应该是自动滚动代码里变量类型未转换引起。

解决:函数wy_img_scroll.prototype.move_to中,_.now_show = n;改为_.now_show = parseInt(n, 10);转换为数字类型。

问题二、提示a is undefined错误。

可能是鼠标移动速度较快,onmouseout事件,目标元素可能已经在文档之外

解决:函数wy_img_scroll.prototype.check_in_dom中,if (a==b) return true;改为if (!a) return false;else if (a==b) return true;增加a不存在的验证。

问题三、IE8不对齐问题。

问题起因:

<div class="wy_img_scroll" id="wy_img_scroll"></div>

被人放进另一个DIV中

变成

<div style="margin:0 auto; width:960px;"><div class="wy_img_scroll" id="wy_img_scroll"></div></div>

于是出现了IE8里发生不对齐问题。具体表现如下

轮播选择了左右滚动模式,从第1张图滚动到第2张图时,最后ul的left值应该为-960px;但滚动到-955px;时就已经停止

 

以下是调试过程

文档外新建一个用来显示的空div,id为test。

函数wy_img_scroll.prototype.move_to的左右滚动代码中增加调试代码

将_.ul.style.left=newoffset+"px";改为

document.getElementById("test").innerHTML+=_.ul.offsetLeft+"_"+newoffset;

_.ul.style.left=newoffset+"px";

document.getElementById("test").innerHTML+="_"+_.ul.offsetLeft+"<br />";

发现一个非常怪异的情况,IE8独有(IE9未测)

offsetset=320,然后

_.ul.style.left=newoffset+"px";

此时再打印

_.ul.offsetLeft的值,竟然是319

此BUG非常诡异……测试起来应该是与外层DIV的margin:0 auto; width:960px;冲突。

 

最后将代码改为调整父级元素的scrollLeft和scrollTop来达到滚动效果,放弃调用left和top值方式。

 

修正后代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
.wy_img_scroll{ position:relative; overflow:hidden;}
	.wy_img_scroll a{ text-decoration:none; font-size:12px; color:#000;}
	.wy_img_scroll img{ vertical-align:middle; border:none;}
	.wy_img_scroll ul{ list-style:none; margin:0; padding:0; position:absolute; left:0; top:0; overflow:hidden; zoom:1;}
		.wy_img_scroll li{ float:left;}
	.wy_img_scroll .guide{ position:absolute; right:5px; bottom:5px; overflow:hidden; zoom:1;}
		.wy_img_scroll .guide a{ display:block; float:left; margin:0 1px; text-align:center; width:20px; height:20px; line-height:20px; background:#FFF; border:#4F2E06 1px solid;}
			.wy_img_scroll .guide a.hover{ background:#EA8B14; color:#FFF; font-weight:bold;}
</style>
</head>
<body>
<div class="wy_img_scroll" id="wy_img_scroll"></div>
<script type="text/javascript">// JS代码在下面
</script>
</body>
</html>


 

function wy_img_scroll(a,b){
	var _=this;
	_.dom = document.getElementById(a);
	_.data = b;
	_.pic_data = b.pic;
	_.scroll_type = b.scroll_type == 2 ? 2 : 1;
	_.auto_time = b.time ? b.time : 5;
}
wy_img_scroll.prototype.check_in_dom = function(a,b){ // 检查a是不是在b之中
	var _=this;
	if (!a) return false;
	else if (a==b) return true;
	else if (!a.parentNode) return false;
	else if (a.parentNode==b) return true;
	else return _.check_in_dom(a.parentNode, b);
};
wy_img_scroll.prototype.init = function(){ // 获取数据写DOM,绑事件
	var _=this, arr_1=[], arr_2=[], str = "";
	// 写HTML
	_.dom.style.width = _.data.width+"px";
	_.dom.style.height = _.data.height+"px";
	for (var i=0, I=_.pic_data.length; i<I; i++){
		if (_.pic_data[i]["link"]){
			arr_1.push('<li><a href="'+_.pic_data[i]["link"]+'" target="_blank" title="'+_.pic_data[i]["title"]+'"><img src="'+_.pic_data[i]["src"]+'" style="width:'+_.data.width+'px; height:'+_.data.height+'px;" /></a></li>');
		}else {
			arr_1.push('<li><a href="javascript:void(0);" οnclick="return false;" title="'+_.pic_data[i]["title"]+'"><img src="'+_.pic_data[i]["src"]+'" style="width:'+_.data.width+'px; height:'+_.data.height+'px;" /></a></li>');
		}
		arr_2.push('<a href="javascript:void(0);" οnclick="return false;" title="'+_.pic_data[i]["title"]+'" guide_flag="'+i+'">'+(i+1)+'</a>');
	}
	_.scroller = document.createElement("div"), _.guider = document.createElement("span");
	_.scroller.style.cssText = "position:absolute; overflow:hidden; width:"+_.data.width+"px; height:"+_.data.height+"px;";
	_.guider.className = "guide";
	_.scroller.innerHTML = "<ul>"+arr_1.join("")+"</ul>";
	_.guider.innerHTML = arr_2.join("");
	_.dom.appendChild(_.scroller);
	_.dom.appendChild(_.guider);
	_.ul = _.dom.getElementsByTagName("ul")[0];
	_.guide_list = _.dom.getElementsByTagName("span")[0].getElementsByTagName("a");
	_.ul.style.width = (_.scroll_type==1?_.data.width:_.data.width*_.pic_data.length)+"px";
	// 绑事件
	if (window.attachEvent){
		_.dom.attachEvent("onmouseover", function(){_.mouseover();});
		_.dom.attachEvent("onmouseout", function(){_.mouseout();});
	}else {
		_.dom.addEventListener("mouseover", function(e){_.mouseover(e);}, false);
		_.dom.addEventListener("mouseout", function(e){_.mouseout(e);}, false);
	}
	_.move_to(0);
	_.start_auto();
};
wy_img_scroll.prototype.move_to = function(n){ // 移动至第n张图
	var _=this;
	_.now_show = parseInt(n, 10);
	for (var i=0, I=_.pic_data.length; i<I; i++) _.guide_list[i].className = i == n ? "hover" : "";
	_.timer_move && window.clearInterval(_.timer_move);
	_.timer_move = window.setInterval(function(){
		if (_.scroll_type == 1){ // 上下
			var final = n*_.data.height;
			if (_.scroller.scrollTop != final){
				var newoffset = (final - _.scroller.scrollTop) / 3 + _.scroller.scrollTop;
				newoffset = Math.abs(final-newoffset) < 2 ? final : newoffset;
				_.scroller.scrollTop = newoffset;
			}else _.timer_move && window.clearInterval(_.timer_move);
		}else { // 左右
			var final = n*_.data.width;
			if (_.scroller.scrollLeft != final){
				var newoffset = (final - _.scroller.scrollLeft) / 3 +_.scroller.scrollLeft;
				newoffset = Math.abs(final-newoffset) <= 2 ? final : newoffset;
				_.scroller.scrollLeft = newoffset;
			}else _.timer_move && window.clearInterval(_.timer_move);
		}
	}, 15);
};
wy_img_scroll.prototype.stop_auto = function(){ // 停止自动滚动
	var _=this;
	_.timer_auto && window.clearInterval(_.timer_auto);
};
wy_img_scroll.prototype.start_auto = function(){ // 开始自动滚动
	var _=this;
	_.timer_auto = window.setInterval(function(){ _.auto();}, _.auto_time*1000);
};
wy_img_scroll.prototype.auto = function(){ // 自动运动事件
	var _=this, n=_.now_show>=_.pic_data.length-1?0:_.now_show+1;
	_.move_to(n);
};
wy_img_scroll.prototype.mouseover = function(){ // 鼠标滑过事件
	var _=this, e=arguments[0]||window.event, obj=e.target||e.srcElement;
	_.stop_auto();
	if (obj.getAttribute("guide_flag")) _.move_to(obj.getAttribute("guide_flag"));
};
wy_img_scroll.prototype.mouseout = function(){ // 鼠标移出事件
	var _=this, e=arguments[0]||window.event, obj=e.relatedTarget||e.toElement;
	if (!_.check_in_dom(obj, _.dom)) _.start_auto();
};

var data = {
	"time":5,
	"width":960,
	"height":250,
	"scroll_type":2,
	"pic":[
		{"src":"http://att.gamefy.cn/201109/att131530177022291.jpg","link":"about:blank","title":"test_1"},
		{"src":"http://att.gamefy.cn/201109/att131521759534930.jpg","link":"about:blank","title":"test_2"},
		{"src":"http://att.gamefy.cn/201108/att131423785570729.jpg","link":"about:blank","title":"test_3"},
		{"src":"http://att.gamefy.cn/201109/att131529721811688.jpg","link":"about:blank","title":"test_4"},
		{"src":"http://att.gamefy.cn/201109/att131486100691248.jpg","link":"about:blank","title":"test_5"}
	]
};
var img_scroller = new wy_img_scroll("wy_img_scroll", data);
img_scroller.init();


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值