不能从类中调用方法,可能是上下文问题。还有如何让一个SlideBox的钉子大小变成自动的?

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

正如你从控制台看到的,它不能调用一个函数。slideDown()我猜测它更像是语法错误,或上下文,但真的不知道如何绕过它。

还有一个额外的问题,我的问题是,如你所见 @keyframe height: 200px; 但是,如果我们调整浏览器的大小,200px对文字来说是不够的,它已经需要250px左右的高度。当我把高度:自动时,它完全没有动画。你知道如何根据里面内容的实际大小来设置吗?

http:/jsfiddle.netcnvx6sd51

console error

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>
javascript class oop accordion
1个回答
1
投票

slideDownslideUp 方法将不会被调用,因为上下文中的 this. addEventListener 绑定 this 值到它正在监听的元素上。所以,你需要改变上下文的 thisAq 类。

您可以通过使用 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);
  }

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