javascript - 怎么解决鼠标移入移除,图片无法迅速切换过来的问题
大家讲道理
大家讲道理 2017-04-11 11:46:50
[JavaScript讨论组]



  
  Document
  


大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回复(1)
高洛峰

代码啥的无大碍,就是变量作用域没有分离开,简单的说在你的循环里打个闭包(构建新的作用域)就可以了。

主要问题在于每个li动画的状态都是不可共享的,每个li有自己的timer时间alpha透明度,如果每个动画状态被共享(就是题主之前的代码),就会出现以下这种情况:

  1. 鼠标移入第一张图片a,执行startMovesetInterval开始根据间隔反复执行。

  2. 比如第一张图片alpha透明度执行到了0.7的时候,移动鼠标到了第二张图片:

    1. 第一张图片执行onmouseout,执行startMove(this, 0.3),但是它是一个异步任务,所以被挂到event loop,在300ms之后执行(关于event loop以及它的异步流程请参考我的这边文章:《JavaScript下的setTimeout(fn,0)意味着什么?》)。

    2. 接着第二张图片的也执行了startMove,但是它的alphatimer都是第一张图片的状态,此时它直接清空了timer,造成的结果就是第一张图片被挂起的300ms任务被clear掉了。

  3. 接着题主就看到了bug现象:第二张发生了动画opacity=1,但是第一张图片opacity也是1

具体修正的代码如下,只需要把共享的变量alpha & timer放到闭包里即可:

var oImg = document.getElementById('imglist');
var oImgLi = oImg.getElementsByTagName('li');
//ES5的func
Array.prototype.forEach.call(oImgLi, function (img) {//传递回调函数,构建新的作用域
    //timer、alpha和startMove,不应该被每个li共享使用,因为每个li都有自己的状态,自己的动画状态(自己的动画时长,alpha透明度)
    var timer = null,
        alpha = 0.3;
    function startMove(obj, iTarget) {
        clearInterval(timer);
        timer = setInterval(function () {
            var speed = 0;
            if (alpha < iTarget) {
                speed = 0.1;
            } else {
                speed = -0.1;
            }

            if (alpha === iTarget) {
                clearInterval(timer);
            } else {
                alpha = (alpha * 10 + speed * 10) / 10;
                obj.style.opacity = alpha;
                obj.style.filter = "alpha(opacity=" + alpha * 100 + ")";
            }
        }, 30);
    }
    img.onmouseover = function () {
        startMove(this, 1);

    };

    img.onmouseout = function () {
        startMove(this, 0.3);
    };
});

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号