JavaScript - 在 display:none 和 display:block 之间添加过渡

问题描述 投票:0回答:9

我正在使用 JavaScript 来切换通知,如下所示。 如何在

display: block
display: none;

之间添加过渡

我不想添加像 jQuery 这样的外部库,因为我只会单独使用

toggle
效果。

var btn = document.querySelector('button');

btn.addEventListener('click', function(){
  var hint = document.getElementById('hint');
  if(hint.style.display == 'none'){
    hint.style.display = 'block';
  }
  else{
    hint.style.display = 'none';
  }

});
div#hint{
  background: gold;
  color: orangered;
  padding: .5em;
  font-weight: bold;
}
<div id='hint'>
  
  <p>This is some hint on how to be safe in this community </p>
   <p>This is another hint on how to be safe in this community </p>
  </div>

<button> show hint </button>

我知道我可以使用 jQuery 来实现这一点,如下所示。

$(document).ready(function(){

$('button').click(function(){
$('#hint').toggle('slow');

});

});
div#hint{
      background: gold;
      color: orangered;
      padding: .5em;
      font-weight: bold;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='hint'>
      
      <p>This is some hint on how to be safe in this community </p>
       <p>This is another hint on how to be safe in this community </p>
      </div>

    <button> show hint </button>

我可以让按钮在

#hint
被切换时逐渐上下移动吗?就像上面的 jQuery 示例一样?我不希望按钮从一个位置到另一个位置。

javascript transition display
9个回答
28
投票

@vothaison 的建议:CSS 过渡

从技术上讲,@vothaison 想使用

setInterval
而不是
setTimeout
,但我认为没有必要。这只是更多的工作。

var hint = document.getElementById('hint');
var btn = document.getElementById('btn_show');

btn.addEventListener('click', function(){
  var ctr = 1;
  hint.className = hint.className !== 'show' ? 'show' : 'hide';
  if (hint.className === 'show') {
    hint.style.display = 'block';
    window.setTimeout(function(){
      hint.style.opacity = 1;
      hint.style.transform = 'scale(1)';
    },0);
  }
  if (hint.className === 'hide') {
    hint.style.opacity = 0;
    hint.style.transform = 'scale(0)';
    window.setTimeout(function(){
      hint.style.display = 'none';
    },700); // timed to match animation-duration
  }
 
});
#hint {
  background: yellow;
  color: red;
  padding: 16px;
  margin-bottom: 10px;
  opacity: 0;
  transform: scale(0);
  transition: .6s ease opacity,.6s ease transform;
}
<div id="hint" style="display: none;">
  <p>This is some hint on how to be safe in this community </p>
  <p>This is another hint on how to be safe in this community </p>
</div>

<button id="btn_show"> Show hint </button>

使用 CSS 动画

var hint = document.getElementById('hint');
var btn = document.getElementById('btn_show');

btn.addEventListener('click', function(){
  hint.className = hint.className !== 'show' ? 'show' : 'hide';
  if (hint.className === 'show') {
    setTimeout(function(){
      hint.style.display = 'block';
    },0); // timed to occur immediately
  }
  if (hint.className === 'hide') {
    setTimeout(function(){
      hint.style.display = 'none';
    },700); // timed to match animation-duration
  }
});
@-webkit-keyframes in {
  0% { -webkit-transform: scale(0) rotate(12deg); opacity: 0; visibility: hidden;  }
  100% { -webkit-transform: scale(1) rotate(0); opacity: 1; visibility: visible; }
}

@keyframes in {
  0% { transform: scale(0) rotate(12deg); opacity: 0; visibility: hidden;  }
  100% { transform: scale(1) rotate(0); opacity: 1; visibility: visible; }
}

@-webkit-keyframes out {
  0% { -webkit-transform: scale(1) rotate(0); opacity: 1; visibility: visible; }
  100% { -webkit-transform: scale(0) rotate(-12deg); opacity: 0; visibility: hidden; }
}

@keyframes out {
  0% { transform: scale(1) rotate(0); opacity: 1; visibility: visible; }
  100% { transform: scale(0) rotate(-12deg); opacity: 0; visibility: hidden;  }
}

#hint {
  background: yellow;
  color: red;
  padding: 16px;
  margin-bottom: 10px;
}

#hint.show {
  -webkit-animation: in 700ms ease both;
  animation: in 700ms ease both;
}

#hint.hide {
  -webkit-animation: out 700ms ease both;
  animation: out 700ms ease both;
}
<div id="hint" style="display: none;">
  <p>This is some hint on how to be safe in this community </p>
  <p>This is another hint on how to be safe in this community </p>
</div>

<button id="btn_show"> Show hint </button>


使用普通 JavaScript

有很多很多方法可以用普通 JavaScript 来完成此类事情,所以这里是一种方法的快速概述:

// you may need to polyfill requestAnimationFrame

var hint = document.getElementById('hint');
var btn = document.getElementById('btn_show');

btn.addEventListener('click', function(){
  var ctr = 0;
  hint.className = hint.className !== 'show' ? 'show' : 'hide';
  
  if (hint.className === 'show') {
    window.setTimeout(function(){
      hint.style.display = 'block';
      fadein();
    },0); // do this asap        
  }
  
  if (hint.className === 'hide') {
    fadeout();
    window.setTimeout(function(){
      hint.style.display = 'none';
    },700); // time this to fit the animation
  }
  
  function fadein(){
    hint.style.opacity = ctr !== 10 ? '0.'+ctr : 1;
    hint.style.transform = ctr !== 10 ? 'scale('+('0.'+ctr)+')' : 'scale(1)';
    ctr++;
    
    if (ctr < 11)
      requestAnimationFrame(fadein);
    
    else
      ctr = 0;
  }

  function fadeout(){
    hint.style.opacity = 1 - ('0.'+ctr);
    hint.style.transform = 'scale('+(1 - ('0.'+ctr))+')';
    ctr++;
    
    if (ctr < 10)
      requestAnimationFrame(fadeout);
    else
      ctr = 0;
  }
});
#hint {
  background: yellow;
  color: red;
  padding: 16px;
  margin-bottom: 10px;
  opacity: 0;
}
<div id="hint" style="display: none;">
  <p>This is some hint on how to be safe in this community </p>
  <p>This is another hint on how to be safe in this community </p>
</div>

<button id="btn_show"> Show hint </button>

说出你对 GreenSock、Velocity.js、jQuery 等的看法——它们都简化了显示和隐藏事物的过程。为什么不直接借用 jQuery 源代码中的 show 和 hide 函数呢?


20
投票

请参阅下面的示例:

var btn = document.querySelector('button');
var hint = document.getElementById('hint');
var height = hint.clientHeight;
var width = hint.clientWidth;
console.log(width + 'x' + height);
// initialize them (within hint.style)
hint.style.height = height + 'px';
hint.style.width = width + 'px';

btn.addEventListener('click', function(){
  if(hint.style.visibility == 'hidden'){
    hint.style.visibility = 'visible';
    //hint.style.opacity = '1';
    hint.style.height = height + 'px';
    hint.style.width = width + 'px';
    hint.style.padding = '.5em';
  }
  else{
    hint.style.visibility = 'hidden';
    //hint.style.opacity = '0';
    hint.style.height = '0';
    hint.style.width = '0';
    hint.style.padding = '0';
  }

});
div#hint{
  background: gold;
  color: orangered;
  padding: .5em;
  box-sizing: border-box;
  overflow: hidden;

  font-weight: bold;
  transition: height 1s, width 1s, padding 1s, visibility 1s, opacity 0.5s ease-out;
}
<div id='hint'>
  
  <p>This is some hint on how to be safe in this community </p>
  <p>This is another hint on how to be safe in this community </p>
</div>

<button> show hint </button>


8
投票

嗨,我不使用 display: blockdisplay:none,而是更改不透明度、高度和填充 请回顾一下这个:

var btn = document.querySelector('button');

btn.addEventListener('click', function() {
  var hint = document.getElementById('hint');
  if (hint.classList.contains('h-hide')) {
    hint.classList.remove('h-hide');
  } else {
    hint.classList.add('h-hide');
  }
});
div#hint {
  display: block;
  background: gold;
  color: orangered;
  padding: .5em;
  font-weight: bold;
  transition: .5s all linear;
  opacity: 1;
  overflow: hidden;
  height: 100px;
}
#hint.h-hide {
  padding: 0;
  opacity: .25;
  height: 0;
}
<div id='hint'>

  <p>This is some hint on how to be safe in this community</p>
  <p>This is another hint on how to be safe in this community</p>
</div>

<button>show hint</button>

这种方法的缺点是我们必须记录 div#hint 高度,并在需要时使用 javascript 更改它。


4
投票

var btn = document.querySelector('button');

btn.addEventListener('click', function(){
  var hint = document.getElementById('hint');
  if(hint.style.visibility == 'hidden'){
    hint.style.visibility = 'visible';
     hint.style.opacity = '1';
  }
  else{
    hint.style.visibility = 'hidden';
     hint.style.opacity = '0';
  }

});
div#hint{
  background: gold;
  color: orangered;
  padding: .5em;

  font-weight: bold;
  transition: visibility 1s, opacity 0.5s linear;
}
<div id='hint'>
  
  <p>This is some hint on how to be safe in this community </p>
   <p>This is another hint on how to be safe in this community </p>
  </div>

<button> show hint </button>

我认为使用显示的可见性是更好的选择


3
投票

在不使用css3过渡的情况下,可以使用js setInterval来改变div的一些css属性,如:

  • 将不透明度从 0 更改为 1

  • 将高度从 0 更改为全高

  • 将宽度从 0 更改为全宽

最初,您应该有

display: none; opacity: 0; height: 0; width: 0'

那么在使用 setInterval 更改其他属性之前,您必须将

display: none
更改为
display: block;

(我猜你知道如何隐藏div)

您还可以使用 setTimeout(),并使用递归技巧。


1
投票

我也尝试过这样做
请看看是否可以帮助您

var btn = document.querySelector('button');
var hint = document.getElementById('hint');
hint.style.opacity = 1;
hint.style.transition = "opacity 1s";

btn.addEventListener('click', function(){

  if(hint.style.opacity == 0 || hint.style.opacity==''){
    hint.style.opacity = 1;

  }
  else{
   hint.style.opacity = 0;

  }

});

1
投票

尝试这样的事情:

var btn = document.querySelector('button');

btn.addEventListener('click', function(){
  var hint = document.getElementById('hint');

  hint.classList.toggle("hide");
});
.hint{
  background: gold;
  color: orangered;
  padding: .5em;
  font-weight: bold;
  
  visibility: visible;
  opacity: 1;
  max-height: 500px;
  transition: visibility 0s, opacity 0.3s, max-height 0.6s linear;
}

.hide {
  visibility: hidden;
  opacity: 0;
  max-height: 0px;
  transition: max-height 0.3s, opacity 0.3s, visibility 0.3s linear;
}
<div id='hint' class="hint">
  
  <p>This is some hint on how to be safe in this community </p>
   <p>This is another hint on how to be safe in this community </p>
  </div>

<button> show hint </button>


1
投票

let redBox = document.getElementById('redBox');
let blueBox = document.getElementById('blueBox');
let [redButton, blueButton] = document.querySelectorAll('button'); //Destructuring 

redButton.addEventListener('click', () => {
    smoothDisplayNone(redBox);
});

blueButton.addEventListener('click', () => {
    smoothDisplayNone(blueBox);
});


//By using smoothDisplayNone() function, you can add this effect to whatever element you want.
function smoothDisplayNone(selectedElement){
    if(!selectedElement.classList.contains('animationDisplayNone')){
        selectedElement.classList.add('animationDisplayNone'); 
        selectedElement.classList.remove('animationDisplayBlock');
    }
    else{
        selectedElement.classList.remove('animationDisplayNone');
        selectedElement.classList.add('animationDisplayBlock'); 
    }
}
#redBox{
    width: 200px;
    height: 200px;
    background-color: red;
}

#blueBox{
    width: 200px;
    height: 200px;
    background-color: blue;
}

.animationDisplayNone{
    animation: smoothDisplayNone 0.5s linear forwards;
}

.animationDisplayBlock{
    animation: smoothDisplayBlock 0.5s linear forwards;
}

/*You should set the width and height according to the size of your element*/
@keyframes smoothDisplayBlock{
    0% { opacity: 0; width: 0px; height: 0px; }
    25% { opacity: 0.25; }
    50% { opacity: 0.50; }
    75% { opacity: 0.75; }
    100% { opacity: 1; width: 200px; height: 200px; }
}

@keyframes smoothDisplayNone {
    0% { opacity: 1; width: 200px; height: 200px; }
    25% { opacity: 0.75; }
    50% { opacity: 0.50; }
    75% { opacity: 0.25; }
    100% { opacity: 0; width: 0px; height: 0px; }
}
<div id="redBox"></div>
<div id="blueBox"></div>
<button type="button" style="margin-top:10px;">Red</button>
<button type="button" style="margin-top:10px;">Blue</button>

代码乍一看很长,但其实很简单易懂。我利用了 CSS 动画的力量来创建平滑的效果。 您可以轻松使用 smoothDisplayNone() 函数。


0
投票

基于 jQuery's
$.toggle
$.show
$.hide
的 Vanilla Javascript。

你只需要传递3个参数:

  1. HTML 元素;
  2. 动画类型 | S = 显示 | H = 隐藏 | T = 切换。默认 = T;
  3. 延迟以毫秒为单位。

示例:

toggleVisibility(document.getElementById('p1'), 'T', 500);

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <style>
            table {
                width: 100%;
            }
        </style>
        <button onclick="toggleVisibility(document.getElementById('p1'), 'T', 500)">SHOW HIDE</button>
        <table id="p1">
            <thead>
                <th>TEST</th>
                <th>TEST</th>
                <th>TEST</th>
            </thead>
            <tbody>
                <tr>
                    <td>TEST</td>
                    <td>TEST</td>
                    <td>TEST</td>
                </tr>
                <tr>
                    <td>TEST</td>
                    <td>TEST</td>
                    <td>TEST</td>
                </tr>
                <tr>
                    <td>TEST</td>
                    <td>TEST</td>
                    <td>TEST</td>
                </tr>
            </tbody>
        </table>
        <script>
            /**
             * Toggle, show or hide the selected HTML element
             * @author Douglas Vicentini ([email protected])
             * @param {HTMLElement} element HTML element to toggle
             * @param {string} type Type of toggle | S = show | H = hide | T = toggle
             * @param {int} delay Delay in milliseconds
             * @see https://github.com/VFDouglas/javascript-toggle-visibility GitHub Repository
             */
            function toggleVisibility(element, type = 'T', delay = 0) {
                if (!element) {
                    console.error('The element should be a valid HTML element');
                    return false;
                }
                // Setting max transition values. Change it to your own preference.
                if (delay < 0) {
                    delay = 0;
                } else if (delay > 10000) {
                    delay = 10000;
                }

                /**
                 * Time which the interval will run
                 * @type {number}
                 */
                let intervalTime = 10;
                let amountLoops  = Math.ceil(delay / intervalTime);
                let doneLoops    = 0;

                /**
                 * Checks if the element is gonna be shown or hidden
                 */
                let showHide;
                if (type == 'H' || (type == 'T' && element.style.display != 'none')) {
                    showHide = 'H';
                } else if (type == 'T' || (type == 'T' && element.style.display == 'none')) {
                    showHide = 'S';

                    // Brifly showing the element to capture the measures (width, height and opacity)
                    element.style.display = '';
                }

                let width   = +window.getComputedStyle(element, null).width.replace('px', '') || 0;
                let height  = +window.getComputedStyle(element, null).height.replace('px', '') || 0;
                let opacity = +window.getComputedStyle(element, null).opacity || 0;

                let widthPerLoop, heightPerLoop, opacityPerLoop;
                let newWidth, newHeight, newOpacity;

                // Calculating the amount of increase/decrease needed according to the amount of loops
                widthPerLoop   = width / amountLoops;
                heightPerLoop  = height / amountLoops;
                opacityPerLoop = opacity / amountLoops;

                const INTERVAL = setInterval(() => {
                    // When the animation is done, we need to remove the custom style attributes
                    if (doneLoops == amountLoops) {
                        element.style.width   = '';
                        element.style.height  = '';
                        element.style.opacity = '';
                        if (showHide == 'H') {
                            element.style.display = 'none';
                        } else {
                            element.style.display = '';
                        }
                        clearInterval(INTERVAL);
                        return false;
                    }

                    if (showHide == 'H') {
                        newWidth   = width - widthPerLoop * (doneLoops + 1);
                        newHeight  = height - heightPerLoop * (doneLoops + 1);
                        newOpacity = opacity - opacityPerLoop * (doneLoops + 1);
                    } else {
                        newWidth   = widthPerLoop * (doneLoops + 1);
                        newHeight  = heightPerLoop * (doneLoops + 1);
                        newOpacity = opacityPerLoop * (doneLoops + 1);
                    }

                    element.style.width   = `${Math.max(newWidth, 0)}px`;
                    element.style.height  = `${Math.max(newHeight, 0)}px`;
                    element.style.opacity = `${Math.max(newOpacity, 0)}`;

                    doneLoops++;
                }, intervalTime);
            }
        </script>
    </body>
</html>

© www.soinside.com 2019 - 2024. All rights reserved.