不透明度过渡适用于淡出,但不适用于淡入

Opacity transition works on fade out, but not fade in

这让我很沮丧。在我 post 代码之前,这里有一个总结:

目标,简单来说:当我双击 X 时,我希望它淡出;当我点击 Y 时,我希望 X 淡入。

方法:我正在使用 CSS 创建实际的淡入和淡出 "animations." 我正在使用 JavaScript 应用 类必要时使用小技巧。

问题:淡入过渡不起作用 -- 元素只是立即出现。让我发疯的是淡入,当立即添加回淡出的对象时,效果非常好。我会在 JS 代码中作为注释更好地解释这一点。

(是的,我在基本元素上添加了 opacity: 1transition: opacity。它根本没有效果。)

代码:

CSS

*.fade-out {
    opacity: 0;
    transition: opacity 400ms;
}
*.fade-in {
    opacity: 1;
    transition: opacity 400ms;
}
*.hide {
    display: none;
    visibility: hidden;
}

JavaScript

$( '#ArtistEmblem' ).on( 'dblclick', function() {
    fadeOut($( '#ArtistEmblem' ));
    fadeIn($( '#btnShowLogo' ));
});
$( '#btnShowLogo' ).on( 'click', function() {
    fadeOut($( '#btnShowLogo' ));
    fadeIn($( '#ArtistEmblem' ));
});

function fadeOut(element) {
    element.addClass( 'fade-out' );

    setTimeout( function () {
        element.addClass( 'hide' );

        /*
        * I tried immediately adding the 'fade-in' class here
        * and it worked -- as soon as the element faded out, it faded
        * back in (using the CSS transition). However, outside of this,
        * it REFUSES to work; everything appears instantly
        */

        console.log('timer triggered');
    }, 400);
}

function fadeIn(element) {
    element.removeClass( 'hide' );
    element.removeClass( 'fade-out' );
    element.addClass( 'fade-in' );
}

相关HTML

<div id="ArtistEmblem">
    <img src="img/logo_artist_2.png" />
</div>

<div id="PopMenu" class="collapse">
    <article>
        <header>
            <b>Debug Menu</b>
        </header>
        <section>
            <button id="btnOpenOverlay">Open Overlay</button>
            <button id="btnShowLogo" class="hide">Show Logo</button>
            <button id="btnClose">Close Menu</button>
        </section>
    </article>
</div>

如果这是显而易见的事情,我深表歉意,但我已经浪费了太多时间来解决它。如果这是最好的答案,我也愿意接受更好、更快或更有效的解决方案。提前致谢!

问题是 "hidden" 元素的初始不透明度默认为 1。你只需要将它设置为 0。同时删除 display: none

*.hide {
    opacity: 0;
}

另外我会做一些重构并删除 setTimeout:

$('#ArtistEmblem').on('click', function() {
    fade($('#btnShowLogo'), $(this));
});
$('#btnShowLogo').on('click', function() {
    fade($('#ArtistEmblem'), $(this));
});

function fade(inElement, outElement) {
    inElement.removeClass('hide');
    inElement.addClass('fade-in');

    outElement.removeClass('fade-in');
    outElement.addClass('fade-out');
}

如果不希望隐藏元素占据space,而希望显示-none,则需要在开始[=]之前设置display: block 15=].

我知道你要的是一个 JS 重的答案,但我强烈建议切换 class 或 "active"、"open" 或类似的东西并使用 CSS随着过渡。少即是多。

这是一个示例 fiddle 我不仅转换了不透明度,还转换了 z-index。如果您打算在下方添加任何元素(例如需要悬停、单击等的按钮),那么这就是这些转换的关键。

JS Fiddle

关键部分:

.container {
  z-index: -1;
  opacity: 0;
  transition: z-index .01s 1s, opacity 1s;
}

.container.active {
  transition: z-index 0s, opacity 1s;
  z-index: 500;
  opacity: 1;
}

编辑

我只是在为我自己的项目摆弄这种类型的东西,并观察 Stripe 如何漂亮地处理他们的导航栏。如此简单的事情改变了一切,这就是指针事件。如果您对它的 support 没意见(值得注意的是 10),这将非常容易集成。这是导航栏中的另一个 fiddle 模拟。

关键部分是指针事件:none,因为如果设置为 none,它会忽略点击事件,几乎就像它不存在一样,但明显存在。我强烈推荐这个。

https://jsfiddle.net/joshmoxey/dd2sts7d/1/

这是一个使用 Javascript Animate API 的示例。不过 IE/Edge 不支持 Animate API。

var element = document.getElementById("fade-in-out")

var button = document.getElementById("x")

button.addEventListener("click", function(event) {
  element.animate([{opacity: 1, visibility: "visible"},{opacity: 0, visibility: "hidden"}], {duration: 2000})
  
  setTimeout(function() { element.remove() }, 2000)
})

button.addEventListener("dblclick", function(event) {
  element && element.animate([{opacity: 0}, {opacity: 1}], {duration: 2000})
})
<input id="x" type="button" value="Click here" />
<div id="fade-in-out"> FADE ME </div>