0

I want to scroll inside a list in a div (or component) by c#/js -call. But what happens is that the hole page is scrolling to the target element. I have this gui: enter image description here

When you click on the button, the content of the list-div (blue) should scroll to the entry 110 like this: enter image description here

But what's actually happens is that the hole page is scrolling like that: enter image description here

In other words: The header and the rest of the page should keep the position. Only inside the list-div should be scrolled.

How can I programmatically scroll inside a div (or component)?

index.html:

<head>
<script type="text/javascript">
    ScrollElementIntoView = element => element.scrollIntoView();
</script> ...

index.razor:

@page "/"
@inject IJSRuntime JsRuntime

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

<div>
    <h3>My List</h3>
    <button @onclick="GoToNextDate">Go to 110</button>
</div>
<br />

<div style="height: 500px; width: 200px; background-color: powderblue; overflow:auto;">
    <ul>
        @foreach (var x in Enumerable.Range(0, 300))
        {
            if (x == 110)
            {
                <span @ref="NextDate"></span>
            }
            <li>@x</li>
        }
    </ul>>
</div>

@code {
    ElementReference NextDate { get; set; }
    List<Func<Task>> AfterRenderAsyncJobs = new();

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        while (AfterRenderAsyncJobs.Any())
        {
            var job = AfterRenderAsyncJobs.First();
            AfterRenderAsyncJobs.Remove(job);
            await job.Invoke();
        }
    }

    private void GoToNextDate()
    {
        AfterRenderAsyncJobs.Add(ScrollToNextDate);
        StateHasChanged();
    }

    private async Task ScrollToNextDate()
    {
        await JsRuntime.InvokeVoidAsync("ScrollElementIntoView", NextDate);
    }
}

MainLayout.razor:

@inherits LayoutComponentBase

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <main>
        <article class="content px-4">
            @Body
        </article>
    </main>
</div>
Frank Mehlhop
  • 1,480
  • 4
  • 25
  • 48

1 Answers1

0

I tested with the different options of scrollIntoView, but nothing was giving satisfactory results for what you want.

This is how I changed your code to work:

    <script type="text/javascript">
        ScrollElementIntoView = element => {
            var target = document.getElementById(element.id);
            target.parentNode.parentNode.scrollTop = target.offsetTop - target.parentNode.parentNode.offsetTop;
        }
    </script>
<div style="height: 500px; width: 200px; background-color: powderblue; overflow:auto;">
    <ul>
        @foreach (var x in Enumerable.Range(0, 300))
        {
            if (x == 110)
            {
                <span @ref="NextDate" id="element-110"></span>
            }
            <li>@x</li>
        }
    </ul>
</div>

Try it and see if it works for you as well.