Кнопка с заменой текста с последовательной сменой символов
Нужно по клику на кнопку изменить асинхронно заголовок кнопки, так как при повторном клики с коротким промежутком функция запускается не завершившисъ
$('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( ' ' );
$( 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>