正如你从控制台看到的,它不能调用一个函数。slideDown()
我猜测它更像是语法错误,或上下文,但真的不知道如何绕过它。
还有一个额外的问题,我的问题是,如你所见 @keyframe height: 200px;
但是,如果我们调整浏览器的大小,200px对文字来说是不够的,它已经需要250px左右的高度。当我把高度:自动时,它完全没有动画。你知道如何根据里面内容的实际大小来设置吗?
JS
window.addEventListener('load', function(){
class Aq
{
constructor()
{
this.asks = document.querySelectorAll('.ask');
this.asks.forEach((ask) => ask.addEventListener('click', this.slideToggle));
}
// it's related on hiegth !!!
slideToggle()
{
let answer = this.parentNode.querySelector('.answer');
if(getComputedStyle(answer).display == 'none')
this.slideDown(answer);
else
this.slideUp(answer);
}
slideDown(answer)
{
let handler = function()
{
answer.classList.remove('active_end');
answer.removeEventListener('animationend', handler);
}
answer.classList.add('active_start');
setTimeout(()=>{ answer.classList.add('active_end')}, 50);
answer.addEventListener('animationend', handler);
}
slideUp(answer)
{
let handler = function()
{
answer.classList.remove('active_start');
answer.classList.remove('hide_start');
answer.addEventListener('animationend', handler);
}
answer.classList.add('hide_start');
answer.addEventListener('animationend', handler);
}
slideUpAll()
{
}
}
new Aq;
})
CSS
html, body{
margin: 0;
background: #eee;
}
.faq{
padding: 30px;
max-width: 600px;
}
.item{
margin: 20px 0;
}
.ask{
font-size: 30px;
margin-bottom: 10px;
cursor: pointer;
}
.answer{
background: #ff0;
overflow: hidden;
display: none;
padding: 0 15px;
}
.active_start{
display: block;
height: 0px;
}
.active_end{
animation: slideDown 1s linear;
animation-fill-mode: forwards;
}
.hide_start{
animation: slideUp 1s linear;
animation-fill-mode: forwards;
}
@keyframes slideDown
{
0%{
height: 0;
}
100%{
height: 200px;
}
}
@keyframes slideUp
{
0%{
height: 200px;
}
100%{
height: 0px;
}
}
超文本标记语言
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>1</title>
<link href="css/styles.css" rel="stylesheet">
</head>
<body>
<div class="faq">
<div class="item">
<div class="ask">0. Вопрос какой-то №1</div>
<div class="answer">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="item">
<div class="ask">2. Вопрос какой-то №2</div>
<div class="answer">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="item">
<div class="ask">3. Вопрос какой-то №3</div>
<div class="answer">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="item">
<div class="ask">4. Вопрос какой-то №4</div>
<div class="answer">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div class="item">
<div class="ask">5. Вопрос какой-то №5</div>
<div class="answer">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
</div>
<script src="js/scripts.js"></script>
</body>
</html>
该 slideDown
或 slideUp
方法将不会被调用,因为上下文中的 this
. addEventListener
绑定 this
值到它正在监听的元素上。所以,你需要改变上下文的 this
至 Aq
类。
您可以通过使用 bind
方法。每个函数都有这个方法,它传递的值应该被用作 this
并用该值创建一个新函数。现在 this
可指 Aq
阶级而非 <div class="ask">
元素。
class Aq {
constructor() {
this.asks = document.querySelectorAll('.ask');
const bindSlideToggle = this.slideToggle.bind(this);
this.asks.forEach((ask) => ask.addEventListener('click', bindSlideToggle));
}
slideToggle() {
let answer = this.parentNode.querySelector('.answer');
if (getComputedStyle(answer).display == 'none')
this.slideDown(answer);
else
this.slideUp(answer);
}
}
或者你可以使用 公共类领域 与箭头函数相结合,以捆绑 this
的类。但他是一个新的功能(目前处于实验阶段),在一些浏览器上可能缺乏支持。
class Aq {
constructor() {
this.asks = document.querySelectorAll('.ask');
this.asks.forEach((ask) => ask.addEventListener('click', this.slideToggle));
}
slideToggle = event => {
let answer = this.parentNode.querySelector('.answer');
if (getComputedStyle(answer).display == 'none')
this.slideDown(answer);
else
this.slideUp(answer);
}
}