只使用CSS,在淡出后隐藏元素

7
我有一个一页显示一页内容的单页应用程序,页面之间使用动画进行过渡。它的工作方式如下:
  1. 用户点击按钮
  2. 发起Ajax调用,在等待响应时页面淡出(opacity: 0)
  3. 如果服务器在淡出完成后500毫秒内未响应,则会出现旋转图标,直到Ajax调用完成
  4. 接收响应后,旋转图标淡出,新页面淡入。
我目前在页面的不透明度上使用CSS 3过渡动画。然而问题是,在旋转图标可见的时间内,用户仍可以与页面的(不可见的)表单进行交互(它并没有消失,只是使用了不透明度变为不可见)。
因此,我想要一个纯CSS的解决方案,在过渡结束时将页面设置为visibility: hidden(我无法使用display: none)。这里应该怎么做呢?

2
将旋转器元素包装在一个宽度和高度均为100%的透明div中怎么样? - Mike
1
这确实可以防止点击元素,但无法阻止切换到表单元素。 - Koen Peters
这些看起来像是拼凑出来的东西。在某些情况下肯定会出问题。 - Koen Peters
这与您的Ajax调用、元素淡出或旋转器一样,不再是“补丁工作”。 - Mike
1
我真的认为在这里使用CSS是错误的方法。使用一个遮罩层<div>来防止点击,以及一个函数noTab(e){e.preventDefault();e.stopPropagation();}; window.addEventListener('keydown',noTab);,然后使用window.removeEventListener('keydown',noTab);来防止按Tab键(和任何输入)是最安全和可靠的方法来完成这个任务(如果JS已启用,哈哈)。 - Sebastian Simon
显示剩余9条评论
4个回答

15

根据 @Rev 的回答,我创建了一个概念验证。它运行得很好(请参见 fiddle)。

当你将类 'fadeOut' 添加到 div 上时,它会淡出并以 visibility: hidden 状态结束。删除类后,它会再次淡入。你可以通过将鼠标悬停在其上来判断它是否真正隐藏:如果隐藏,则不再给出“文本选择”鼠标指针。

HTML

<div class="page">
    Lorem ipsum etc etc etc. 
</div>

CSS

  .page {
      -moz-animation-name: fadeIn;
      -webkit-animation-name: fadeIn;
      -ms-animation-name: fadeIn;
      animation-name: fadeIn;
      -moz-animation-duration: 1s;
      -webkit-animation-duration: 1s;
      -ms-animation-duration: 1s;
      animation-duration: 1s;
      -moz-animation-timing-function: ease-in-out;
      -webkit-animation-timing-function: ease-in-out;
      -ms-animation-timing-function: ease-in-out;
      animation-timing-function: ease-in-out;
      -moz-animation-fill-mode: forwards;
      -webkit-animation-fill-mode: forwards;
      -ms-animation-fill-mode: forwards;
      animation-fill-mode: forwards;  
    }

    .page.fadeOut {
      -moz-animation-name: fadeOut;
      -webkit-animation-name: fadeOut;
      -ms-animation-name: fadeOut;
      animation-name: fadeOut;
    }

    @-moz-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}
    @-webkit-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}
    @-ms-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}
    @-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}

    @-moz-keyframes fadeOut { 0% { opacity: 1; visibility: visible; }  100% { opacity: 0; visibility: hidden; }} 
    @-webkit-keyframes fadeOut { 0% { opacity: 1; visibility: visible; }  100% { opacity: 0; visibility: hidden; }} 
    @-ms-keyframes fadeOut { 0% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden; }} 
    @-keyframes fadeOut { 0% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden;  }} 

一些额外的备注:

  1. 如果在 .page 元素中有子元素,它们显式地设置了 visibility: visible,那么它们将对鼠标交互作出反应。这是因为它们不是隐藏的,只是由于不透明度为 0 而不可见。例如,Twitter Bootstrap 的 collapse 插件就是这样做的。您可以通过将它们的 visibility 设置为 inherit 而不是 visible 来解决这个问题。这将导致它们仅在其父级可见时才可见。例如,可以使用以下附加 CSS 使折叠插件行为正常:

    .page .collapse { visibility: inherit; }

  2. 这在 IE 9 及以下版本中无效。

  3. 您需要像我的代码中看到的浏览器前缀才能使此功能正常工作。我没有使用前缀进行测试,最新版本的 Chrome(42)和 Firefox(37)都没有正常工作。这很丑陋,但可以通过使用类似 SASS 和 Compass 这样的工具来简化。下面是使用该方法的相同代码:

SASS with Compass

.page { 
  @include animation(fadeIn 1s ease-in-out forwards); 
}

.page.fadeOut { 
  @include animation-name(fadeOut); 
}

@include keyframes(fadeIn) {
  0% { opacity: 0; visibility: hidden; }
  100% { opacity: 1; visibility: visible; }
}

@include keyframes(fadeOut) {
  0% { opacity: 1; visibility: visible; }  
  100% { opacity: 0; visibility: hidden; }
}

1
1%和99%的框架有什么意义?没有它们似乎对我也能工作。 - Mike
嗯,你说得对。我以为可见性会在动画开始时立即交换,但实际上并不是这样。这将导致开关机而没有任何淡入淡出效果。但我错了,所以我会把它们删除。谢谢! - Koen Peters

3

不完全是仅使用JS,但在启动淡入动画时,还要向表单容器添加以下CSS类:

.disableMouse * {
  pointer-events: none;
}

这将禁用点击(但不会禁用滚动)。在所有现代浏览器中都可以使用,但IE仅支持11版本及以上。如果您需要支持IE10及更早版本,则这可能不是最佳选项。


好想法。我以前从未听说过mouse-events。但是它只停止了鼠标事件。您仍然可以使用键盘切换到它并更改值。请参见http://jsfiddle.net/fpjpghLd/。 - Mike
我需要它只使用CSS。此外,像prevent评论指出的那样,还存在问题。 - Koen Peters
是啊...如果有一个键盘等效的pointer-events就好了。我没有看到任何方法可以在没有脚本禁用表单元素的情况下实现这一点。 - Jeff Clarke

0

如果您的唯一目的是禁用交互,您可以在页面上使用pointer-events: none(IE11+),或者在顶部放置一个浮动阻止器,例如:

.page.loading {
    position: relative;
}
.page.loading:after {
    content: ' ';
    display: block;
    position: relative;
    background: white;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

0

我相信仅凭 CSS 是无法完成的。你可以研究一下 JavaScript 的 transitionend

你也可以尝试使用 CSS 动画而不是过渡效果。我知道你不能过渡 visibility: hidden;,但你可能可以在 100% 的动画关键帧上设置这个效果。


transitionend事件对我来说是新的,看起来很酷。不过它是JS的,我正在寻找一个纯CSS的解决方案。关键帧也很有趣,我会研究一下。 - Koen Peters
是的,我已经好几年没用了,但它还是挺好的。如果你在移动设备上,我建议你多研究一下动画方面。祝你好运! - JacobTheDev
1
我基于你的关键帧想法创建了一个可行的示例。有关详细信息,请参见我的答案。感谢这个想法! - Koen Peters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接