73127


JavaScriptでボタンをクリックすると新しく要素を追加するコードを書いてボタンを押すと要素が追加されるんですが、その追加された際のアニメーションを下からふわっとフェードインするようにしたいです。

[code]

    イメージとして最初は要素が2つある。この最初の2つはふわっとさせられる。
    <div class="dlcard effect"></div>
    <div class="dlcard effect"></div>
    
    ボタンクリックでdlcadが追加されていく。これが追加される瞬間をふわっとさせたい。
    <div class="dlcard effect"></div>
    
[/code]

最初はopacityを0にして、translateで下の方にずらしてあります。

[code]

    .showeffect {
        opacity: 0;
        transform: translate(0, 45px);
        transition: all 500ms;
    }
    
[/code]

画面が読み込まれた際は下記のコードでふわっと出現するようにしています。

[code]

    class effect {
        constructor(){
            this.DOM = {}
            this.DOM.showeffects = document.querySelectorAll('.showeffect')
            this._addEvent();
        }
    
        showUp(){
            this.DOM.showeffects.forEach((showeffect) => {
                showeffect.style.opacity = 1;
                showeffect.style.transform = 'translate(0, 0)';
            });
        }
    
        _addEvent(){
            window.addEventListener("load", this.showUp.bind(this))
        }
    }
    
    new effect();
    
[/code]

画面が読み込まれた際は上手く追加出来たのですが、ボタンをクリックして追加される要素に対してどのようにイベントを割り当てて良いかわかりません。

だいぶ読みづらいコードで恐縮ですが要素を追加するコードを載せておきます。

[code]

    class AddDLcard {
        constructor() {
            this.DOM = {};
            this.DOM.container = document.querySelector('.add__button');
            this.DOM.dlcardWrap = document.querySelector('.dlcardWrap');
            this.eventType = this._getEventType();
            this._addEvent();
        }
    
        _getEventType() {
            //スマホで見る場合このプロパティが存在する事になる    True        False
            return window.ontouchstart ? 'touchstart' : 'click';
        }
    
        _addEvent() {
            // thisを束縛しないとaddEventListerが取得される。ためMobileMenu内の関数なので束縛が必要
            this.DOM.container.addEventListener(this.eventType, this._click.bind(this));
            
        }
    
        _click() {
            const dlcards = document.querySelectorAll('.dlcard');
            this.DOM.dlcard = dlcards[dlcards.length - 1];
            let addElement = this.DOM.dlcard.cloneNode(true);
            addElement.querySelector('.dlcard__title > .dlcard__videoName').innerText = '';
            let thumbnail = addElement.querySelector('.dlcard__thumbnail');
            thumbnail.querySelector('img').src = 'images/pinkguy.jpg';
            const classNames = thumbnail.querySelector('.dlcard__thumbnail--cover').classList;
            let thumbnailClassName = classNames[1];
            let dlcardNumber = thumbnailClassName.match(/[0-9]+/)[0];
            thumbnail.querySelector('.dlcard__thumbnail--cover').classList.replace(thumbnailClassName, `thumbnail-${Number(dlcardNumber) + 1}`);
            addElement.querySelector('.dlcard__url > input').value = '';
            addElement.querySelector('.dlcard__url > input').placeholder = 'URL：https://www.youtube.com/watch?v=';
            this.DOM.dlcardWrap.appendChild(addElement);
        }
    }
    
    new AddDLcard();
    
[/code]


CC BY-SA 4.0
2021-01-06T06:55:24.357
73118
2021-01-07T01:47:24.793
2021-01-07T01:47:24.793
3060
22565
question
javascript html
Javascriptで後から追加した要素をふわっと出現させるには


setTimeoutを使用することで、消えた状態で追加された要素にcssを上書きさせることで実装する事が出来ました。


CC BY-SA 4.0
2021-01-07T01:22:47.313
73126
2021-01-07T01:22:47.313
22565
73118
answer


まず前提条件としてイベントを割り当てる必要はないはずです。  
大事なことはイベントとDOMと効果（アニメーション）をきちんと切り離すことです。

新しく読み込んだ時にはアニメーションを追加する必要があるのでロードイベントを用いて効果を発火させましたが、  
新しく追加するコンテンツについてはイベントを検知せず、効果を実行してしまえばよいと思います

（誤）  
クリックイベント→DOMの生成および設置→イベントの発火→効果の発動

（正）  
クリックイベント→DOMの生成および設置→効果の発動

またDOMの生成をcloneで実行しているのですでに  
showeffect.style.opacity = 1;  
showeffect.style.transform = 'translate(0, 0)';  
が適用されたDOMになってしまっているでしょう。そこもきちんとリセットしましょう。

また即時にスタイルを当てると効果が見えないので、setinterval等を用いて遅延をかけるとアニメーションが良く見えるでしょう。

[code]

    class effect {
        constructor(){
            this.DOM = {}
            this.DOM.showeffects = document.querySelectorAll('.showeffect')
            this._addEvent();
        }
    
        showUp(){
            this.DOM.showeffects.forEach((showeffect) => {
                showeffect.style.opacity = 1;
                showeffect.style.transform = 'translate(0, 0)';
            });
        }
    
        _addEvent(){
            window.addEventListener("load", this.showUp.bind(this))
        }
    }
    
    new effect();
    
    class AddDLcard {
        constructor() {
            this.DOM = {};
            this.DOM.container = document.querySelector('.add__button');
            this.DOM.dlcardWrap = document.querySelector('.dlcardWrap');
            this.eventType = this._getEventType();
            this._addEvent();
        }
    
        _getEventType() {
            //スマホで見る場合このプロパティが存在する事になる    True        False
            return window.ontouchstart ? 'touchstart' : 'click';
        }
    
        _addEvent() {
            // thisを束縛しないとaddEventListerが取得される。ためMobileMenu内の関数なので束縛が必要
            this.DOM.container.addEventListener(this.eventType, this._click.bind(this));
            
        }
    
        _click() {
            const dlcards = document.querySelectorAll('.dlcard');
            this.DOM.dlcard = dlcards[dlcards.length - 1];
            let addElement = this.DOM.dlcard.cloneNode(true);
            addElement.style.opacity = 0;
            addElement.style.transform = 'translate(0, 45px)';
            this.DOM.dlcardWrap.appendChild(addElement);
            setTimeout(function(){
              addElement.style.opacity = 1;
              addElement.style.transform = 'translate(0, 0)';
            }, 100);
    
            
    
        }
    }
    
    new AddDLcard();
[/code]

[code]

    .showeffect {
        opacity: 0;
        transform: translate(0, 45px);
        transition: all 500ms;
    }
[/code]

[code]

    イメージとして最初は要素が2つある。この最初の2つはふわっとさせられる。
    <div class="dlcardWrap">
      <div class="dlcard showeffect">1</div>
      <div class="dlcard showeffect">2</div>
    </div>
    
    <button class="add__button">追加</button>
[/code]

本来はeffectクラスで行っている効果の部分を切り出すか、もしくは別のクラスに委任するか必要がありますが、それは設計上の問題なのでここでは単純に書かせていただきました。

P.S.  
また、いただいたソースだとそのまま動かなかったです。より再現性が取れるソースで記述できるとより回答しやすくなり、回答も集まりやすいでしょう。  
※クラス名があっていないshoweffectなのかeffectなのか？dlcardWrapやadd__buttonがソースに存在しない  
※DOMを追加する際に、ソースには存在しないクラスや機能が入っている


CC BY-SA 4.0
2021-01-07T01:31:24.987
73127
2021-01-07T01:31:24.987
22665
73118
answer