Кнопка с заменой текста с последовательной сменой символов

Нужно по клику на кнопку изменить асинхронно заголовок кнопки, так как при повторном клики с коротким промежутком функция запускается не завершившисъ

$('button').on( 'click', animate_text )

function animate_text( e ) {
  let _this = $( e.target ).closest( 'button' ),

    parent_old_text = _this.children( 'div:visible' ),

    old_text = parent_old_text.text();

  parent_old_text.html( old_text.replace( /./g, '<span>$&</span>' ) );

  let spans = parent_old_text.find( 'span' ),

    delay = 1,

    clean_old_text = false;

  for ( let i = spans.length; i >= 0; i -- ) {
    setTimeout( function() {
      let span = spans[ i ];

      $( span ).css( { display: 'none' } );

      if ( i == 0 ) clean_old_text = true;
    }, 50 * delay );

    delay ++
  }

  let add_new_text = setInterval( function() {
    if ( clean_old_text ) {
      clearInterval( add_new_text );

      let parent_new_text = _this.children( 'div:hidden' ),

        new_text = parent_new_text.text();

      parent_new_text.html( new_text.replace( /./g, '<span>$&</span>' ) );

      spans = parent_new_text.find( 'span' );

      spans.css( { display: 'none' } );

      parent_old_text.css( { display: 'none' } );

      parent_new_text.css( { display: 'inline-block' } );

      delay = 1;

      $( spans ).each( function( i, span ) {
        setTimeout( function() {
          if ( /\s/.test( $( span ).text() ) ) $( span ).html( '&nbsp' );

          $( span ).css( { display: 'inline-block' } );

          if ( i == spans.length - 1 ) _this.find( '.blink-cursor' ).remove()
        }, 50 * delay );

        delay++
      } )
    }
  }, 300 )
}
button {
  width: 120px;
  height: 30px;
}
button * {
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>
  <div>показать</div>
  <div style="display:none">скрыть</div>
</button>
<button>
  <div>открыть</div>
  <div style="display:none">закрыть</div>
</button>


Ответы (0 шт):