0

因此,我创建了以下函数来淡入淡出元素并传入一个我想要淡入淡出的 div,在这种情况下,我想在用户单击我网站上的图像缩略图时显示一个图片库弹出窗口。我还传递了一个速度值(iSpeed),超时用于它的时间值。在这种情况下,我使用 25 (25ms)。

我已经逐步完成了此功能,同时它似乎按预期运行。如果当前不透明度小于 1,则它会递增,并且在超时后会重新调用自身,直到不透明度达到 1。当它达到 1 时,它会停止淡入淡出并返回。

因此,在逐步完成之后,我取消了断点并尝试查看它的运行情况,但由于某种原因,我的画廊立即出现而没有任何褪色感。

var Effects = new function () {

    this.Fading = false;

    this.FadeIn = function (oElement, iSpeed) {

        //set opacity to zero if we haven't started fading yet.
        if (this.Fading == false) {
            oElement.style.opacity = 0;
        }

        //if we've reached or passed max opacity, stop fading
        if (oElement.style.opacity >= 1) {
            oElement.style.opacity = 1;
            this.Fading = false;
            return;
        }
        //otherwise, fade
        else {
            this.Fading = true;
            var iCurrentOpacity = parseFloat(oElement.style.opacity);
            oElement.style.opacity = iCurrentOpacity + 0.1;
            setTimeout(Effects.FadeIn(oElement, iSpeed), iSpeed);
        }

    }

}

这是我设置画廊的地方。

this.Show = function (sPage, iImagesToDisplay, oSelectedImage) {

        //create and show overlay
        var oOverlay = document.createElement('div');
        oOverlay.id = 'divOverlay';
        document.body.appendChild(oOverlay);

        //create and show gallery box
        var oGallery = document.createElement('div');
        oGallery.id = 'divGallery';
        oGallery.style.opacity = 0;
        document.body.appendChild(oGallery);

        //set position of gallery box
        oGallery.style.top = (window.innerHeight / 2) - (oGallery.clientHeight / 2) + 'px';
        oGallery.style.left = (window.innerWidth / 2) - (oGallery.clientWidth / 2) + 'px';

        //call content function
        ImageGallery.CreateContent(oGallery, sPage, iImagesToDisplay, oSelectedImage);

        //fade in gallery
        Effects.FadeIn(oGallery, 25);

    }

谁能帮帮我?

另外,我正在使用 IE10,我也尝试过 Chrome,结果相同。

谢谢,安迪

4

3 回答 3

2

这一行:

setTimeout(Effects.FadeIn(oElement, iSpeed), iSpeed);

使用给定参数调用 Effects.FadeIn,并将其返回值输入setTimeout. 这与 完全一样foo(bar()),它立即调用 bar,然后将其返回值提供给foo.

由于您的FadeIn函数不返回函数,这将是问题所在。

也许你的意思是:

setTimeout(function() {
    Effects.FadeIn(oElement, iSpeed);
}, iSpeed);

...尽管您最好创建一次该功能并重用它。

例如,我认为这可以满足您的需求,但无需在每个循环上重新创建函数:

var Effects = new function () {

    this.FadeIn = function (oElement, iSpeed) {
        var fading = false;

        var timer = setInterval(function() {
            //set opacity to zero if we haven't started fading yet.
            if (fading == false) { // Consider `if (!this.Fading)`
                oElement.style.opacity = 0;
            }

            //if we've reached or passed max opacity, stop fading
            if (oElement.style.opacity >= 1) {
                oElement.style.opacity = 1;
                clearInterval(timer);
            }
            //otherwise, fade
            else {
                fading = true;
                var iCurrentOpacity = parseFloat(oElement.style.opacity);
                oElement.style.opacity = iCurrentOpacity + 0.1;
            }
        }, iSpeed);
    };
};
于 2013-10-31T22:21:48.113 回答
1

你的代码有很多问题。立即出现的元素的一个罪魁祸首是您调用 setTimeout 不是使用函数而是使用函数的结果,因为 Effects.FadeIn 将立即执行。

setTimeout(function(){Effects.FadeIn(oElement, iSpeed)}, iSpeed);

可能会按照您的意愿行事。

但说真的,你可能不应该重新发明这个轮子。jQuery将允许您轻松地淡入和淡出元素,而CSS 过渡允许您通过添加或删除 CSS 类来实现元素淡化。

于 2013-10-31T22:24:03.527 回答
1

TJMoMolog对这个 bug 的看法都是正确的:你在Effects.FadeIn将结果传递给之前立即调用函数setTimeout——这意味着它Effects.FadeIn会一次又一次地同步调用自身,直到oElement.style.opacity >= 1达到条件。

您可能知道也可能不知道,在事件循环的一个回合内发生的许多 UI 更新将在下一次重绘(或类似的事情)时一起批处理,因此您不会看到任何类型的转换。

这个 jsFiddle包括建议的 JS 解决方案,以及我认为您可能会发现更好的替代方法:只需添加一个带有transition 属性的 CSS 类。这将导致更流畅的动画。请注意,如果您选择这条路线,您可能还需要包含一些供应商前缀。

于 2013-10-31T22:31:01.453 回答