使用显示块 CSS Javascript 获取模态淡入效果

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

我正在努力让模式在单击按钮时获得动画效果。模态框隐藏时不得占用空间。所以我想在未显示时使用 display none 。单击按钮时,模式需要淡入。现在我找到了一个解决方案,我认为可以使其发挥作用。但它仍然不起作用。谁能告诉我为什么它不起作用?我怎样才能让它工作?

<!DOCTYPE html>
<html lang="en">
    
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>
    
<body>
  <h2>Animating from <code>display:none</code> to <code>display:block</code></h2>
  <div id="box" class="box"></div>
    
  <button>TOGGLE VISIBILITY</button>
</body>

<script src="script.js"></script>

</html>
.box {
  background: goldenrod;
  width: 300px;
  height: 300px;
  margin: 30px auto;
  transition: all 2s linear;
  display: none;
}
        
.show {
  display: block;
}
          
.visuallyshow {
  opacity: 0;
}
        
button {
  display: block;
  margin: 0 auto;
}
let box = document.getElementById('box'),
  btn = document.querySelector('button');
    
btn.addEventListener('click', function () {
  if (box.classList.contains('show')) {
    box.classList.remove('show');
    setTimeout(function () {
      box.classList.remove('visuallyshow');
    }, 20);
  } else {
    box.classList.add('visuallyshow');
    box.addEventListener('transitionend', function (e) {
      box.classList.add('show');
    }
    // , {
    //   capture: false,
    //   once: true,
    //   passive: false
    // }
    );
  }
}, false);
javascript css animation modal-dialog fadein
3个回答
1
投票

这是您需要做的:

  • 盒子最初应具有
    opacity: 0
    ,并且
    .visuallyshow
    类应将其更改为 1。
  • setTimeout
    中的延迟应该是2000,而不是20。2秒等于2000毫秒。
  • 您需要切换添加和删除类的顺序。显示盒子时,首先需要添加
    display: block
    ,然后添加
    opacity: 1
  • 显示元素时,不应使用
    transitionend
    事件处理程序,而应使用延迟 1 毫秒的
    setTimeout
    。这将允许浏览器重新渲染布局,因此能够发生转换。

let box = document.getElementById('box'),
    btn = document.querySelector('button');

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

    if (box.classList.contains('show')) {
        box.classList.remove('visuallyshow');
        setTimeout(function () {
            box.classList.remove('show');
        }, 2000);
    } else {
        box.classList.add('show');
        setTimeout(() => {
            box.classList.add('visuallyshow');
        }, 1);
    }

}, false);
.box {
  background: goldenrod;
  width: 300px;
  height: 300px;
  margin: 30px auto;
  transition: opacity 2s linear;
  display: none;
  opacity: 0;
}

.show {
  display: block;
}

.visuallyshow {
  opacity: 1;
}


button {
  display: block;
  margin: 0 auto;
}
<h2>Animating from <code>display:none</code> to <code>display:block</code></h2>
<div id="box" class="box"></div>

<button>TOGGLE VISIBILITY</button>


1
投票
.modal {
  display: none;
  opacity: 0;
  transition: opacity: 1s;
}

.modal.show {
  display: block;
  opacity: 1;
}

如果您

...classList.add('show')
到模态,应该可以工作。

我认为你的不起作用的原因是因为为了应用转换,它首先需要一个初始值,然后才能知道要转换到什么。在上述情况下,您首先需要告诉它不透明度为 0,之后您实际上可以将其“过渡”为 1。


1
投票

问题是您的 .box 样式表默认情况下没有

"opacity: 0;"
,这就是它无法顺利过渡的原因。除此之外,您的转换速度设置为 2000 毫秒,这非常慢。

我在此小提琴链接中提出了一个可行的解决方案: https://jsfiddle.net/32oyu6wf/3/

我所做的是修改了 .box 样式表以具有

"opacity: 0;"
并调整了 javascript 事件监听器以相应地触发类。

稍微检查一下小提琴,您可以在项目中重复使用相同的方法。

let box = document.getElementById('box'),
  btn = document.querySelector('button');

btn.addEventListener('click', function() {
  if (box.style.display == "block") {
    box.classList.remove("visuallyshow")
    setTimeout(function() {
      box.style.display = "none"
    }, 210);

  } else {
    box.style.display = "block";
    setTimeout(function() {
      box.classList.add("visuallyshow")
    }, 20);
  }

}, false);
.box {
  background: goldenrod;
  width: 300px;
  height: 300px;
  margin: 30px auto;
  transition: all 0.3s linear;
  display: none;
  opacity: 0;
}

.visuallyshow {
  opacity: 1;
}

button {
  display: block;
  margin: 0 auto;
}
<h2>Animating from <code>display:none</code> to <code>display:block</code></h2>


    <button>TOGGLE VISIBILITY</button>
    <div id="box" class="box"></div>

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