Open ericdum opened 11 years ago
虽然说这是一个很常见的东西,但真要论起来,其实有很多地方可以优化。
比如淘宝首页的图片轮播,如果一个顾客的鼠标像我这样傻逼得晃过去晃过来,被他经过的轮播就“停止”了。
注意鼠标移动的轨迹和轮播的大图片,如果用户在轮播周期内反复_经过_轮播元素,图片轮播就会“永远”停止。而下方的图片已经经过了几次轮播了。
而同样的事情如果发生在心动游戏的官网上会,这不会有任何不符合预期的行为发生,鼠标悬停轮播停止,鼠标离开不影响轮播进程。
注意鼠标移动的轨迹和轮播的大图片
引题结束,希望能引起你的兴趣,如若不然你应该不会看到这行字。。。或者下行字。。。
这个是我12年刚进入心动时写的,需求很简单——图片轮播、右下角链接。
为了实现这个需求,代码也可以很简单:
源代码:
https://github.com/ericdum/mujiang.info/blob/master/share/marquee.js
捡重要的代码看:
function marquee(data, options){ //设置、初始化.... //第二、三步 var the = this; //第四步 this.controller.find('span').live('click', function(){ the.start(0, $(this).index()); }); //第五步 this.start(); } function start( timeout, index ) { this.clear(); //清除timeout this.promise(timeout, index); } function next(index) { // 执行动画 .... this.current = index; this.promise();//设置下次轮播 } function promise( timeout, index ){ timeout = timeout>=0 ? timeout : this.timeout; var the = this; this.tm = window.setTimeout(function(){ the.next(index); }, timeout); } function clear() { window.clearTimeout(this.tm); }
因为我们认为用户鼠标悬停代表用户对图片产生了关注,所以悬停要暂停图片播放,就需要在上面初始化的方法中时候加入:
this.hovering = false; $(this).hover(function(){ the.hovering = true; }, function(){ the.hovering = false; the.start(); });
然后再next方法中加入:
if( this.hovering ) return;
这就可以了(另外要做好点击切换时的处理)。完成以后便发现了文章一开头提到的问题。
为了解决这个问题,首先想到的是在鼠标移走之后让图片立即改变。代码很简单,把上面第二段代码hover中对start的调用改成the.start(500)就好了——鼠标离开后500毫秒变换图片。
//hover(function(){...},function(){... the.start(500)
但这就随之而来了另一个问题,如果用户老是经过这个地方,图片岂不是会不停地换——频率太快。
解决方案是如果图片播放的时间不足,则鼠标悬停对轮播不造成影响。实现的方法就是新增一个stopping状态。在next函数中判断hovering==true时,把它设置成true。而后在hover的第二个函数中判断:
$(this).hover(function(){ the.hovering = true; }, function(){ the.hovering = false; if( the.stopping ){ the.stopping = false; the.start(500); } }); //in next function if( this.hovering ) { this.stopping = true; return; }
除了上面的工作以外还有个显而易见的问题:这种广告图片都是比较大的jpg图片(形状、色彩丰富),压缩的空间不大(jpg有损)。并且除了第一张,其他图片再3秒内是不需要显示的。所以决定分批下载,先下载第一张图,等第一张图下载完成之后再下载后续的图(这个时候这些图已经会排在下载队列的最后了)。
方案是扩展先前定义的initImages方法:
function initImages(){ var the = this; this.marquee.empty();//保持卫生 this.appendImage(0, function(){ for(var i=1; i<the.data.length; i++){ the.appendImage(i); } }); } function appendImage(index, callback){ //检查参数,准备DOM对象... img.load(callback); img.attr('src', data[0]); //插入DOM... }
图片延迟加载和以及本身就是靠js加载的第一张图片,必然会有概率发生图片还未加载完就要被用户观看的问题。所以必然要有野菊花。
解决方案更简单了,直接css加到了root元素的背景上,图片载入后自然盖住他,完美无缝,切换每张图没载入都可以显示到菊花。
js方面修改appendImage方法,防止未加载的图片被用户看到(那个飘渺的白框)。
function appendImage(index, callback){ //... img.hide(); img.load(function(){ $(this).show(); callback(); }); img.attr('src', data[0]); //... }
7777
今天分享一个很常见的东西——图片轮播。
虽然说这是一个很常见的东西,但真要论起来,其实有很多地方可以优化。
比如淘宝首页的图片轮播,如果一个顾客的鼠标像我这样傻逼得晃过去晃过来,被他经过的轮播就“停止”了。
注意鼠标移动的轨迹和轮播的大图片,如果用户在轮播周期内反复_经过_轮播元素,图片轮播就会“永远”停止。而下方的图片已经经过了几次轮播了。
而同样的事情如果发生在心动游戏的官网上会,这不会有任何不符合预期的行为发生,鼠标悬停轮播停止,鼠标离开不影响轮播进程。
注意鼠标移动的轨迹和轮播的大图片
引题结束,希望能引起你的兴趣,如若不然你应该不会看到这行字。。。或者下行字。。。
这个是我12年刚进入心动时写的,需求很简单——图片轮播、右下角链接。
为了实现这个需求,代码也可以很简单:
源代码:
https://github.com/ericdum/mujiang.info/blob/master/share/marquee.js
捡重要的代码看:
悬停问题
因为我们认为用户鼠标悬停代表用户对图片产生了关注,所以悬停要暂停图片播放,就需要在上面初始化的方法中时候加入:
然后再next方法中加入:
这就可以了(另外要做好点击切换时的处理)。完成以后便发现了文章一开头提到的问题。
为了解决这个问题,首先想到的是在鼠标移走之后让图片立即改变。代码很简单,把上面第二段代码hover中对start的调用改成the.start(500)就好了——鼠标离开后500毫秒变换图片。
但这就随之而来了另一个问题,如果用户老是经过这个地方,图片岂不是会不停地换——频率太快。
解决方案是如果图片播放的时间不足,则鼠标悬停对轮播不造成影响。实现的方法就是新增一个stopping状态。在next函数中判断hovering==true时,把它设置成true。而后在hover的第二个函数中判断:
性能问题
除了上面的工作以外还有个显而易见的问题:这种广告图片都是比较大的jpg图片(形状、色彩丰富),压缩的空间不大(jpg有损)。并且除了第一张,其他图片再3秒内是不需要显示的。所以决定分批下载,先下载第一张图,等第一张图下载完成之后再下载后续的图(这个时候这些图已经会排在下载队列的最后了)。
方案是扩展先前定义的initImages方法:
菊花问题
图片延迟加载和以及本身就是靠js加载的第一张图片,必然会有概率发生图片还未加载完就要被用户观看的问题。所以必然要有野菊花。
解决方案更简单了,直接css加到了root元素的背景上,图片载入后自然盖住他,完美无缝,切换每张图没载入都可以显示到菊花。
js方面修改appendImage方法,防止未加载的图片被用户看到(那个飘渺的白框)。
其他问题