sinfella
sinfella

Reputation: 286

Can't get any Javascript file working properly in blazor

relatively new to blazor..

I have been using MVC, and webforms but made a dive into blazor and .net core...

What a pain it has been so far from start to finish... Anyway my issue...

I am trying to follow this codepen, typewriter text `https://codepen.io/hckkiu/pen/KKzgEMr`

Very easy to implement anywhere but blazor... So i have my CSS and javascript file loading correctly but the output is never there..

enter image description here

Can anyone tell me why its not loading / blazor / c#

The javascript is blinking but no text continuation.

<div class='containers'>
    <div class="bodys">
        <p class='typewriter'>
            I'm a
            <span class='typewriter-text' data-text='[ "photographer. ", "designer. ", "developer. " ]'></span>
        </p>
    </div>
</div>

Javascript

$(document).ready(function () {

    typing(0, $('.typewriter-text').data('text'));

    function typing(index, text) {

        var textIndex = 1;

        var tmp = setInterval(function () {
            if (textIndex < text[index].length + 1) {
                $('.typewriter-text').text(text[index].substr(0, textIndex));
                textIndex++;
            } else {
                setTimeout(function () { deleting(index, text) }, 2000);
                clearInterval(tmp);
            }

        }, 150);

    }

    function deleting(index, text) {

        var textIndex = text[index].length;

        var tmp = setInterval(function () {

            if (textIndex + 1 > 0) {
                $('.typewriter-text').text(text[index].substr(0, textIndex));
                textIndex--;
            } else {
                index++;
                if (index == text.length) { index = 0; }
                typing(index, text);
                clearInterval(tmp);
            }

        }, 150)

    }

});

CSS

bodys {
    width: 100%;
    height: 100%;
    background-color: #3a3a3a;
}

.containers {
    display: flex;
    align-items: center;
    width: 100%;
    height: 100%;
}

.typewriter {
    font-family: sans-serif;
    color: black;
    padding-left: 30px;
    display: block;
}

.typewriter-text {
    padding-right: 10px;
    color: red;
    border-right: solid #ffe509 7px;
    text-transform: uppercase;
    animation: cursor 1s ease-in-out infinite;
    font-weight: bold;
}

@keyframes cursor {
    from {
        border-color: #ffe509;
    }

    to {
        border-color: transparent;
    }
}

@media (max-width: 767.98px) {
    .typewriter {
        font-size: 35px;
    }
}

@media (min-width: 768px) {
    .typewriter {
        font-size: 60px;
    }
}

Upvotes: 3

Views: 1905

Answers (2)

Mister Magoo
Mister Magoo

Reputation: 9029

glad to see you are trying out Blazor!

The first lesson should be - Don't try to do everything in JavaScript. Take what you want to do and translate it to Blazor. Using JS libraries and components is an advanced topic - start with plain C# Blazor - Blazor University is a good resource.

Here is a working repl : https://blazorrepl.com/repl/GOvEwjOY58lmz0ao15

and the code for that - there is no JavaScript required for this in Blazor.

Note: in the real world you would make this implement IDisposable and use a cancellation token to cancel the long running Task

    <div class='container'>
      <p class='typewriter'>I'm a 
      <span class='typewriter-text'>@typewriterText</span>
      </p>
    </div>
    @code {
        string[] jobs = { "photographer. ", "designer. ", "developer. " };
        string typewriterText;
        Task worker;
        protected override void OnInitialized()
        {
            worker = Typewriter();
        }
        async Task Typewriter()
        {
            var index = 0;
            while(true)
            {
                var textIndex = 1;
    
                while( textIndex < jobs[ index ].Length + 1 ) 
                {
                  typewriterText = jobs[ index ].Substring( 0, textIndex );
                  textIndex++;
                  StateHasChanged();
                  await Task.Delay(150);
                };
                
                StateHasChanged();
                await Task.Delay(2000);
                
                textIndex = jobs[ index ].Length;
                
                while ( textIndex + 1 > 0 ) 
                {
                    typewriterText = jobs[ index ].Substring( 0, textIndex );
                    textIndex--;
                    StateHasChanged();
                    await Task.Delay(150);
                };
    
                index++;
                if ( index == jobs.Length ) 
                { 
                    index = 0; 
                }
            }
        }
    }

Upvotes: 4

Umair
Umair

Reputation: 5501

You will have to call the javascript after your component/page is rendered, $(document).ready will not help in this case as the component might be rendered after the page load.

See below example to call the javascript that will then do the functionality that you want:

In your component:

@inject IJSRuntime JSRuntime;

// or

[Inject] protected IJSRuntime JSRuntime { get; set; }

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await JSRuntime.InvokeVoidAsync("startTyping");
    }
}

Javascript file:

window.startTyping = () => {
    typing(0, $('.typewriter-text').data('text'));
    // other js code here
}

See here for reference: https://learn.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-3.1

Upvotes: 2

Related Questions