您的位置:首页 > 其它

写一个[图片无缝向左连续滚动]究竟有多复杂

2016-04-14 18:01 681 查看
“向左”,“滚动”,这是要解决的要点,而这两方向,都与对象的scrollLeft属性相关。对于scrollLeft,直白理解就是:对象的内容(即其整个innerHTML),如果能够左右滚动的话(这是前提条件),它在某时刻左边滚动了的像素距离(结果为数字,并且该属性是可写可读的)。这里需要注意的是,虽然document.body.scrollLeft需要考虑兼容性问题,但其它的div的scrollLeft是兼容的,这里无需考虑兼容性问题。

所以不管读取或者设置scrollLeft的值,都必须有个前提条件:能左右滚动!!!
比如有一个id=mydiv的DIV,在一个不能左右滚动的前提条件下,比如其overflow设置为visible或者overflow没有设置.它会怎么样呢?

mydiv会表现为被内容自动撑开,内容有多长多宽,div就自动多长多宽,div不出现滚动条。这时候scrollLeft读取到的值为0,并且无论如何设置scrollLeft的值,它都为0。这可以说明,如果其不能左右滚动,那scrollLeft就一直为0.

接下来,我们准备制造出“能左右滚动”的这种前提条件。

要出现scrollLeft,就必须:能左右滚动。这个限制会让我们将对象的overflow属性设置成auto,hidden,scroll,并且限制对象的width。但往往auto只会造成上下滚动而非左右。所以我们只能考虑scroll与hidden。

考虑以下代码:

<style>
#mydiv{width:600px;height:100px; margin:100px; border: 3px solid #8ec2f5; padding:0; background:#d6e9fc;overflow:scroll;}
</style>
<div id="mydiv">
内容...
</div>


它的效果是:



我们虽然设置了overflow为scroll。它能左右滚动了吗?不能。虽有滚动条,但呈灰色,不能左右拉动。因为overflow:scroll的前提是内容超出指定的宽高才会出现的,由于里边的内容不够长,最终导致不会出现左右方面的scroll点。

在实际场景下,我们的内容是可以很长的,放几张美女图片,增长内容,比如:

<style>
#mydiv{width:600px; height:100px; margin:20px;border: 3px solid #8ec2f5; padding:0; background:#d6e9fc; overflow:scroll;}

img {width:100px; height:100px;}
</style>
<div id="mydiv">
<a href="#"><img src="http://h.hiphotos.baidu.com/image/h%3D300/sign=1655a14ec15c10383b7ec8c28211931c/2cf5e0fe9925bc31a365a0cc59df8db1cb1370ae.jpg"></a>
<a href="#"><img src="http://d.hiphotos.baidu.com/image/pic/item/503d269759ee3d6d26a5088c44166d224f4ade12.jpg"></a>
<a href="#"><img src="http://h.hiphotos.baidu.com/image/pic/item/f703738da9773912f4750a26ff198618367ae222.jpg"></a>
<a href="#"><img src="http://g.hiphotos.baidu.com/image/pic/item/0ff41bd5ad6eddc447d63bbc3edbb6fd52663347.jpg"></a>
<a href="#"><img src="http://d.hiphotos.baidu.com/image/pic/item/b21bb051f81986187d1660c34ded2e738bd4e620.jpg"></a>
<a href="#"><img src="http://d.hiphotos.baidu.com/image/pic/item/1f178a82b9014a90b559c9faae773912b31bee16.jpg"></a>
<a href="#"><img src="http://a.hiphotos.baidu.com/image/pic/item/b3fb43166d224f4a58fcfc540ef790529822d114.jpg"></a>
<a href="#"><img src="http://f.hiphotos.baidu.com/image/pic/item/e61190ef76c6a7ef6b057d72fafaaf51f3de6647.jpg"></a>
</div>


其效果如下:



内容已经足够长的啦。但它出现了上下滚动条,没有出现左右滚动条。因为它自动换行了。我们让它浮动吧,希望它能变成行内元素。

#mydiv a {float:left;margin:0 10px;}


但浮动这是没作用的。mydiv的宽高已经固定,a作为其子元素,如何浮动到一定宽度一定会自动换行。我们不能变化mydiv的宽度,那如何办呢?大家应该都能想到:
再套一个div,作为mydiv的子元素,设定其宽很长很长。
代码如下:

<!DOCTYPE html>
<html>
<style>
#mydiv{width:600px; height:100px; margin:20px;border: 3px solid #8ec2f5; padding:0; background:#d6e9fc; overflow:scroll;}

#mysubdiv{margin:0; padding:0;width:9999px; height:100px;}
img {width:100px; height:100px;}
#mydiv a {float:left;margin:0 10px;}
</style>
<div id="mydiv">
<div id="mysubdiv">
<a href="#"><img src="http://h.hiphotos.baidu.com/image/h%3D300/sign=1655a14ec15c10383b7ec8c28211931c/2cf5e0fe9925bc31a365a0cc59df8db1cb1370ae.jpg"></a>
<a href="#"><img src="http://d.hiphotos.baidu.com/image/pic/item/503d269759ee3d6d26a5088c44166d224f4ade12.jpg"></a>
<a href="#"><img src="http://h.hiphotos.baidu.com/image/pic/item/f703738da9773912f4750a26ff198618367ae222.jpg"></a>
<a href="#"><img src="http://g.hiphotos.baidu.com/image/pic/item/0ff41bd5ad6eddc447d63bbc3edbb6fd52663347.jpg"></a>
<a href="#"><img src="http://d.hiphotos.baidu.com/image/pic/item/b21bb051f81986187d1660c34ded2e738bd4e620.jpg"></a>
<a href="#"><img src="http://d.hiphotos.baidu.com/image/pic/item/1f178a82b9014a90b559c9faae773912b31bee16.jpg"></a>
<a href="#"><img src="http://a.hiphotos.baidu.com/image/pic/item/b3fb43166d224f4a58fcfc540ef790529822d114.jpg"></a>
<a href="#"><img src="http://f.hiphotos.baidu.com/image/pic/item/e61190ef76c6a7ef6b057d72fafaaf51f3de6647.jpg"></a>
</div>
</div>


效果:



现在终于左右能滚动了。此时,我们的scrollLeft可以派上用场了:

<script>
var mydiv = document.getElementById('mydiv');
mydiv.scrollLeft=300;
document.title=mydiv.scrollLeft;
</script>


效果如下:



既然scrollLeft是可读可写的,并且在一开始的时候,它的值为0.我们现在让scrollLeft每秒增加10。一个向左滚动的原型就出现了。

<script>
var mydiv = document.getElementById('mydiv');
var myScroll = function(){
mydiv.scrollLeft=mydiv.scrollLeft+10;
document.title=mydiv.scrollLeft;
}
window.setInterval(myScroll,1000);
</script>


效果如下:



目前它的缺点就是:由于9999px长度的mysubdiv的空白还要走。



那有什么办法,让它不走空白,而走重复的图片内容呢?大家很容易就想到,将空白的内容用重复的图片占用掉就可以了。最容易的办法,就是再diy几个mysubdiv的innerHTML,接在原先的后面,要做到这样,可以采用再套子div的办法,代码如下:

<!DOCTYPE html>
<html>
<style>
#mydiv{width:600px; height:100px; margin:20px;border: 3px solid #8ec2f5; padding:0; background:#d6e9fc; overflow:hidden;}

#mysubdiv{margin:0; padding:0;width:9999px; height:100px;}
#mypicdiv{margin:0; padding:0;width:auto; height:100px; float:left;}
#mypicdiv2{margin:0; padding:0;width:auto; height:100px;float:left;}
img {width:100px; height:100px;}
#mydiv a {float:left;margin:0 10px;}
</style>
<div id="mydiv">
<div id="mysubdiv">
<div id="mypicdiv">
<a href="#"><img src="http://h.hiphotos.baidu.com/image/h%3D300/sign=1655a14ec15c10383b7ec8c28211931c/2cf5e0fe9925bc31a365a0cc59df8db1cb1370ae.jpg"></a>
<a href="#"><img src="http://d.hiphotos.baidu.com/image/pic/item/503d269759ee3d6d26a5088c44166d224f4ade12.jpg"></a>
<a href="#"><img src="http://h.hiphotos.baidu.com/image/pic/item/f703738da9773912f4750a26ff198618367ae222.jpg"></a>
<a href="#"><img src="http://g.hiphotos.baidu.com/image/pic/item/0ff41bd5ad6eddc447d63bbc3edbb6fd52663347.jpg"></a>
<a href="#"><img src="http://d.hiphotos.baidu.com/image/pic/item/b21bb051f81986187d1660c34ded2e738bd4e620.jpg"></a>
<a href="#"><img src="http://d.hiphotos.baidu.com/image/pic/item/1f178a82b9014a90b559c9faae773912b31bee16.jpg"></a>
<a href="#"><img src="http://a.hiphotos.baidu.com/image/pic/item/b3fb43166d224f4a58fcfc540ef790529822d114.jpg"></a>
<a href="#"><img src="http://f.hiphotos.baidu.com/image/pic/item/e61190ef76c6a7ef6b057d72fafaaf51f3de6647.jpg"></a>
</div>

<div id="mypicdiv2"></div>
</div>
</div>
<script>
var mydiv = document.getElementById('mydiv');
var mypicdiv = document.getElementById('mypicdiv');
var mypicdiv2 = document.getElementById('mypicdiv2');
mypicdiv2.innerHTML = mypicdiv.innerHTML;

var myScroll = function(){
mydiv.scrollLeft=mydiv.scrollLeft+10;
document.title=mydiv.scrollLeft;
}
window.setInterval(myScroll,1000);
</script>




目前它要走的空白已经短了,为了让它的空白全部消除,最原先我们的办法可以是:
1.多造几个mypicdiv那样的浮动块,占够位置。
2.将mysubdiv的width改少一些。
但这两种办法都无法彻底将空白删除,不是剩余空白就是不够空白导致换行。
那有没有一种办法能够不用消灭空白而直接可以“连接向左滚动”的呢?
办法就是:当刚好滚动了一个mypicdiv的距离的时候("刚好"的意思,这需要很精细的刻度,所以需要让scrollLeft每次变化尽量少,即每次变化+1,而一个mypicdiv的距离,需要用到对象属性:offsetWidth),又重新回到mypicdiv去滚动(即让scrollLeft=0)。这样,就会连续滚动mypicdiv,并且后边接着的mypicdiv2就能造成无缝的效果。
代码如下:

<script>
var mydiv = document.getElementById('mydiv');
var mypicdiv = document.getElementById('mypicdiv');
var mypicdiv2 = document.getElementById('mypicdiv2');
mypicdiv2.innerHTML = mypicdiv.innerHTML;

var myScroll = function(){
if(mydiv.scrollLeft>=mypicdiv.offsetWidth){
mydiv.scrollLeft = 0;
}else{
mydiv.scrollLeft=mydiv.scrollLeft+1;
}
document.title=mydiv.scrollLeft;
}

/*
//根据人眼每帧看到24幅画面以上则认为是连续动画效果,让1000/24~=42.当数量大于24时,speed小于42,设置speed为小于42的数值最佳,让滚动显示无缝,流畅。
//另外,速度越小,滚动越快
*/
var speed = 20;
window.setInterval(myScroll,speed);
</script>


以上代码调整了变化的速度,以及大小。
效果如下:





这样就简单地完成了一个图片无缝向左滚动。设置mydiv的overflow:hidden,去除滚动条(但隐式地有“能左右滚动”),让美观更好一点。注意:document.title=mydiv.scrollLeft;这一行只用于调试查看,实际用途中必须删除。

从html结构(及相关CSS设置)上看,需要达到的条件如下图所示:



从JS角度上看,需要知道的技术也不过如下:
innerHTML,scrollLeft,offsetWidth,setInterval

所以如果需要简单地写一个图片无缝向左滚动,还是可以轻易完成的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: