如何在给出显示后平滑淡入/淡出元素:无值

时间:2016-04-26 02:01:48

标签: javascript html css

我知道Stack Overflow上有很多类似于这个的问题,所有这些问题都是通过使用abort而不是visibility:hidden属性来解决的。我遇到的问题是我认为我必须使用display:none,因为我需要用一个替代div来填充隐藏的div的空间,display:none只会保留该空间而使其不可见。

我的目标:点击 + 按钮后,visibility:hidden元素正确淡出。在这个动画之后,我有一个计算500毫秒的JavaScript行,然后给faded div一个包含nav的类。

问题是当点击现在的 - 按钮时,我将元素返回其display:none属性并删除赋予其模糊/淡入淡出效果的类。 但是,该元素只是立即弹回屏幕,而不是一个漂亮的渐变/转换。没有动画

在继续使用display:block属性的同时,我对如何解决这个问题感到茫然。 感谢您的帮助,我没有使用像jQuery这样的库,只是简单的普通Javascript。

display:none
var expand = document.getElementById("expansion");

function removeElm() {
  "use strict";
  document.querySelector("nav").classList.add("removed");
  document.querySelector("#description").classList.remove("removed");
}

function expandF() {
  "use strict";
  var navLi = document.querySelectorAll("li"), i;
  
  if (!document.querySelector("nav").classList.contains("out")) {
    document.querySelector("nav").classList.add("out");
    document.querySelector("body").style.background = "#dff";
    document.getElementById("expansion").innerHTML = "-";
    document.getElementById("expansion").style.background = "#f00";
    
    for (i = 0; i < navLi.length; i++) {
      navLi[i].classList.add("rsHover");
    }   
    setTimeout(removeElm, 500);
  } else {
    document.querySelector("nav").classList.remove("removed");
    document.querySelector("#description").classList.add("removed");
    document.querySelector("nav").classList.remove("out");
    document.querySelector("body").style.background = "#fff";
    document.getElementById("expansion").innerHTML = "+";
    document.getElementById("expansion").style.background = "#222";
    
    for (i = 0; i < navLi.length; i++) {
      navLi[i].classList.remove("rsHover");
    }
  }
}

expand.addEventListener("click", expandF);
/*///////////////////////////////// __NAV__ /////////////////////////////////*/
nav {
  display: inline-block; position: relative; top: 50%; right: 19px;
  -webkit-transform: translateY(-50%); transform: translateY(-50%); margin: auto
}
nav ul:after { content: ""; display: block; clear: both } /* << clearfix */

nav ul { font-size: 100%; text-transform: uppercase; margin: 0; padding: 0 }
nav li { width: 150px; height: 150px; list-style: none; float: left; margin: 5px}
nav li:hover { background: #055; color: #eee; cursor:pointer }
nav span {
  display: block; position: relative; top: 50%; -webkit-transform: translateY(-50%);
  transform: translateY(-50%)
}
/*///////////////////////////////// SECTION /////////////////////////////////*/
#description {
  display: inline-block; position: relative; top: 50%; right: 19px;
  -webkit-transform: translateY(-50%); transform: translateY(-50%); margin: auto
}
/*///////////////////////////////// _MISC__ /////////////////////////////////*/
.removed { display: none !important }
.rsHover:hover { background: #dff }
.out {
  -webkit-filter: blur(60px); filter: blur(60px); color: #fff; 
  -webkit-transform: scale(0.1, 0.9); transform: scale(0.1, 0.9);
  -webkit-transform: translateY(-50%); transform: translateY(-50%); font-size: 110%;
}
/*///////////////////////////////// _ANIM__ /////////////////////////////////*/
body{ -webkit-transition:2s ease; transition:2s ease }

nav{
  -webkit-transition:color 1s ease, -webkit-filter 1s ease, -webkit-transform 1s ease;
  transition:color 1s ease, -webkit-filter 1s ease, -webkit-transform 1s ease;
  transition:filter 1s ease, color 1s ease, transform 1s ease;
  transition:filter 1s ease, color 1s ease, transform 1s ease, -webkit-filter 1s ease, 
  -webkit-transform 1s ease;
}

3 个答案:

答案 0 :(得分:1)

您需要在设置display: block后强制浏览器呈现元素,以确保元素在文档流中,否则它不会进行任何转换或动画。使用reflow:

您当前隐藏(display: none)状态的元素:

<div style="display: none; opacity: 0; transition: opacity 500ms"></div>

JS使其在流程中转换为不透明度:1:

div.style.display = 'block';
div.clientHeight; // Forces the browser to "reflow"
div.style.opacity = 1; // Now the element will transition from opacity: 0 to opacity: 1

其中div是HTMLElement对象。请注意,opacity只是一个示例。

我强烈建议您阅读本文以了解更多信息(因为它是一个非常复杂的主题):http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/

修改:将currentHeight更改为clientHeight

答案 1 :(得分:0)

您也可以在同一个按钮中添加或删除事件侦听器,以便执行不同的操作。

我不是JS的专家,但我已经看到,有时候,如果你的javascript在同一个函数中更改类和样式,浏览器将执行更改同时搞乱你的一些动画。

在下面的这个例子中,我使用一个肮脏的技巧来强制代码做一个接一个的事情。如果你不这样做,那么fadein将不起作用。

// To remove
document.querySelector('.remove').addEventListener('click', remove);

function remove() {
  // Reconfig the button
  var button = document.querySelector('.remove');
  button.removeEventListener('click', remove);
  button.classList.remove('remove');
  button.classList.add('add');
  button.addEventListener('click', add); // New functionality added
  // Now make your changes
  var element = document.querySelector('.test');
  element.classList.add('fadeout');
  setTimeout(function() {
    element.style.display = 'none';
  }, 500);
}

function add() {
  var button = document.querySelector('.add');
  button.removeEventListener('click', add);
  button.classList.remove('add');
  button.classList.add('remove');
  button.addEventListener('click', remove);
  var element = document.querySelector('.test');
  element.style.display = 'inline-block';
  // Dirty trick incomming!
  setTimeout(function() { // force the change of the class after the change of display
    element.classList.remove('fadeout');
  }, 1); // do this after 1ms of the previews command
}
.remove,
.add {
  cursor: pointer;
}
.test {
  display: inline-block;
  transition: all 0.5s;
  background: blue;
  color: white;
  opacity: 1;
}
.fadeout {
  opacity: 0;
}
<div class="remove">Click to toggle element below</div>
<div class="test">testing block</div>

答案 2 :(得分:-1)

var expand = document.getElementById("expansion");

function removeElm() {
  "use strict";
  document.querySelector("nav").classList.add("removed");
  document.querySelector("#description").classList.remove("removed");
}

function expandF() {
  "use strict";
  var navLi = document.querySelectorAll("li"), i;
  
  if (!document.querySelector("nav").classList.contains("out")) {
    document.querySelector("nav").classList.add("out");
    document.querySelector("body").style.background = "#dff";
    document.getElementById("expansion").innerHTML = "-";
    document.getElementById("expansion").style.background = "#f00";
    
    for (i = 0; i < navLi.length; i++) {
      navLi[i].classList.add("rsHover");
    }   
    setTimeout(removeElm, 500);
  } else {
    document.querySelector("nav").classList.remove("removed");
    document.querySelector("#description").classList.add("removed");
    document.querySelector("nav").classList.remove("out");
    document.querySelector("body").style.background = "#fff";
    document.getElementById("expansion").innerHTML = "+";
    document.getElementById("expansion").style.background = "#222";
    
    for (i = 0; i < navLi.length; i++) {
      navLi[i].classList.remove("rsHover");
    }
  }
}

expand.addEventListener("click", expandF);
/*///////////////////////////////// __NAV__ /////////////////////////////////*/
nav {
  display: inline-block; position: relative; top: 50%; right: 19px;
  -webkit-transform: translateY(-50%); transform: translateY(-50%); margin: auto
}
nav ul:after { content: ""; display: block; clear: both } /* << clearfix */

nav ul { font-size: 100%; text-transform: uppercase; margin: 0; padding: 0 }
nav li { width: 150px; height: 150px; list-style: none; float: left; margin: 5px}
nav li:hover { background: #055; color: #eee; cursor:pointer }
nav span {
  display: block; position: relative; top: 50%; -webkit-transform: translateY(-50%);
  transform: translateY(-50%)
}
/*///////////////////////////////// SECTION /////////////////////////////////*/
#description {
  display: inline-block; position: relative; top: 50%; right: 19px;
  -webkit-transform: translateY(-50%); transform: translateY(-50%); margin: auto
}
/*///////////////////////////////// _MISC__ /////////////////////////////////*/
.removed { display: none !important }
.rsHover:hover { background: #dff }
.out {
  -webkit-filter: blur(60px); filter: blur(60px); color: #fff; 
  -webkit-transform: scale(0.1, 0.9); transform: scale(0.1, 0.9);
  -webkit-transform: translateY(-50%); transform: translateY(-50%); font-size: 110%;
}
/*///////////////////////////////// _ANIM__ /////////////////////////////////*/
body{ -webkit-transition:2s ease; transition:2s ease }

nav{
  -webkit-transition:color 1s ease, -webkit-filter 1s ease, -webkit-transform 1s ease;
  transition:color 1s ease, -webkit-filter 1s ease, -webkit-transform 1s ease;
  transition:filter 1s ease, color 1s ease, transform 1s ease;
  transition:filter 1s ease, color 1s ease, transform 1s ease, -webkit-filter 1s ease, 
  -webkit-transform 1s ease;
}
<head>
  <style>
    html,body { height: 100%; text-align: center; color: #222; margin: 0 }
    #expansion {
      float:left; position: relative; top: 50%; -webkit-transform: translateY(-50%);
      transform: translateY(-50%); width: 28px; height: 28px; padding: 5px;
      margin: auto; color: #666; font-size: 150%
    }
    #expansion:hover { background: #222; color: #eee; cursor:pointer; }
  </style>
</head>

<body>
  <div id="expansion">+</div>
  <nav>
    <ul>
      <li><span>one</span>
      </li>
      <li><span>two</span>
      </li>
    </ul>
  </nav>
  <section id="description" class="removed">
    <h1>about web</h1>
    <p>
      WEB is a reference of...
    </p>
  </section>
</body>