{"id":13466674,"url":"https://github.com/ljbc1994/BlazorIntersectionObserver","last_synced_at":"2025-03-26T00:31:21.808Z","repository":{"id":34904263,"uuid":"188595299","full_name":"ljbc1994/BlazorIntersectionObserver","owner":"ljbc1994","description":"🔎 Intersection Observer API wrapper for Blazor applications","archived":false,"fork":false,"pushed_at":"2025-01-28T13:38:47.000Z","size":1174,"stargazers_count":61,"open_issues_count":11,"forks_count":14,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-04T08:41:24.841Z","etag":null,"topics":["blazor","intersectionobserver","intersectionobserver-api","typescript"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ljbc1994.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-05-25T17:37:08.000Z","updated_at":"2025-01-28T13:59:03.000Z","dependencies_parsed_at":"2024-01-07T10:28:03.455Z","dependency_job_id":"62c1d791-aeb6-43a1-a4d4-f9148c985b97","html_url":"https://github.com/ljbc1994/BlazorIntersectionObserver","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljbc1994%2FBlazorIntersectionObserver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljbc1994%2FBlazorIntersectionObserver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljbc1994%2FBlazorIntersectionObserver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ljbc1994%2FBlazorIntersectionObserver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ljbc1994","download_url":"https://codeload.github.com/ljbc1994/BlazorIntersectionObserver/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245566098,"owners_count":20636390,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor","intersectionobserver","intersectionobserver-api","typescript"],"created_at":"2024-07-31T15:00:48.305Z","updated_at":"2025-03-26T00:31:21.152Z","avatar_url":"https://github.com/ljbc1994.png","language":"C#","readme":"# BlazorIntersectionObserver\n\n[![Package Version](https://img.shields.io/nuget/v/BlazorIntersectionObserver.svg)](https://www.nuget.org/packages/BlazorIntersectionObserver)\n[![NuGet Downloads](https://img.shields.io/nuget/dt/BlazorIntersectionObserver.svg)](https://www.nuget.org/packages/BlazorIntersectionObserver)\n[![License](https://img.shields.io/github/license/ljbc1994/BlazorIntersectionObserver.svg)](https://github.com/ljbc1994/BlazorIntersectionObserver/blob/master/LICENCE)\n\n\u003e A comprehensive wrapper around the Intersection Observer API, giving you all the goodness of observing intersections in a performant way.\n\nThis is a wrapper around the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) so that you can use it in `Blazor` for .NET 5. It has the same API structure with convenience methods and components for a better dev experience. It works with both Blazor WebAssembly and Blazor Server. \n\n## Get Started\n\n### 1. Installation\n\nInstall `BlazorIntersectionObserver` through NuGet.\n\n```bash\n\u003e dotnet add package BlazorIntersectionObserver\n```\n\n### 2. Register the service\n\nNow you'll need to add the service to the service configuration.\n\n#### WebAssembly (Program.cs)\n\n```cs\nusing Ljbc1994.Blazor.IntersectionObserver;\n\npublic class Program\n{\n    public static async Task Main(string[] args)\n    {\n        var builder = WebAssemblyHostBuilder.CreateDefault(args);\n        builder.Services.AddIntersectionObserver();\n    }\n}\n```\n\n*OR*\n\n#### Server (Startup.cs)\n\n```cs\nusing Ljbc1994.Blazor.IntersectionObserver;\n\npublic class Startup {\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddIntersectionObserver();\n    }\n}\n```\n\n### 3. Use it!\n\nFor the quickest setup, use the `IntersectionObserve` component. This provides an implicit context\nobject which contains the observer entry! Easy!\n\n#### Component setup\n\n```razor\n@using Ljbc1994.Blazor.IntersectionObserver.Components\n\n\u003cIntersectionObserve\u003e\n    \u003cdiv @ref=\"context.Ref.Current\"\u003e\n        Hey... I'm @(context.IsIntersecting ? \"in view\": \"out of view\")\n    \u003c/div\u003e\n\u003c/IntersectionObserve\u003e\n```\n\n*OR*\n\n#### Service setup\n\nTo directly use the service, you just need to inject it and observe the element(s).\n\n```razor\n@using Ljbc1994.Blazor.IntersectionObserver\n@inject IIntersectionObserverService ObserverService\n\n\u003cimg @ref=\"ImageElement\" src=\"@(IsIntersecting ? \"https://www.placecage.com/g/500/500\" : \"\")\"/\u003e\n\n@functions {\n    public ElementReference ImageElement { get; set; }\n    public bool IsIntersecting { get; set; }\n    \n    protected override async Task OnAfterRenderAsync(bool firstRender)\n    {\n        if (firstRender) \n        {\n            await SetupObserver();\n        }\n    }\n\n    public async void SetupObserver()\n    {\n        await ObserverService.Observe(ImageElement, (entries) =\u003e\n        {\n            var entry = entries.FirstOrDefault();\n            IsIntersecting = entry.IsIntersecting;\n            StateHasChanged();\n        });\n    }\n}\n```\n\n## Documentation and Usage\n\n### Options\n\nYou can pass through `options` to the `ObserverService` methods, these are the same as the Intersection Observer API options.\n\n#### Example\n\n```cs\nvar options = new IntersectionObserverOptions {\n    Root = BodyRef, \n    Threshold = new List\u003cdouble\u003e { 0.25, 0.5, 1 },\n    RootMargin = \"10px 10px 10px 10px\"\n};\n```\n\n### Service Methods\n\n#### `Observe`\n\nThis a shorthand way of observing an element by providing:\n- The element you want to observe.\n- The callback to trigger on an intersection update.\n- The intersection observer options.\n\nThis returns an `IntersectionObserver` instance, allowing you to `disconnect` the observer or `unobserve` an element. Or if you wish, observe additional elements.\n\n```cs\nvar observer = await ObserverService.Observe(ElementRef, (entries) =\u003e {\n    IsIntersecting = entries.FirstOrDefault().IsIntersecting;\n    StateHasChanged();\n}, options);\n```\n\n#### `Create`\n\nThe `Create` method follows the same approach as the Intersection Observer API, you create the observer and then pass elements you wish to observe by calling the `Observe` method on the observer instance. To create the observer, provide the following:\n\n- The callback to trigger on an intersection update.\n- The intersection observer options.\n\nThis returns an `IntersectionObserver` instance, allowing you to `Observe` elements. This also provides the ability to `disconnect` or `unobserve` the element.\n\n```cs\nvar observer = await ObserverService.Create((entries) =\u003e {\n    IsIntersecting = entries.FirstOrDefault().IsIntersecting;\n    StateHasChanged();\n}, options);\n\nawait observer.Observe(FirstImage);\nawait observer.Unobserve(FirstImage);\n```\n\n### `IntersectionObserver` Methods\n\n#### `Observe` \n\nTo observe an element, provide the element reference to the `IntersectionObserver` instance by calling `Observe`.\n\n```cs\nobserver.Observe(ElementReference);\n```\n\n#### `Unobserve`\nTo unobserve an element, provide the element reference to the `IntersectionObserver` instance by calling `Unobserve`.\n\n```cs\nobserver.Unobserve(ElementReference);\n```\n\n#### `Disconnect`\nTo disconnect the observer, call `Disconnect` on the `IntersectionObserver` instance.\n\n```cs\nobserver.Disconnect();\n```\n\nThis will remove all the observed elements from the observer, i.e.\n\n```razor\n@using Ljbc1994.Blazor.IntersectionObserver\n@implements IAsyncDisposable\n@inject IIntersectionObserverService ObserverService\n\n\u003cdiv @ref=\"ImageRef\"\u003e\u003c/div\u003e\n\n@functions {\n    private IntersectionObserver Observer;\n    @* Code... *@\n\n    public async ValueTask DisconnectAll()\n    {\n        if (this.Observer != null)\n        {\n            await this.Observer.Disconnect();\n        }\n    }\n}\n\n```\n\n#### `Dispose`\nTo remove the observer, call `Dispose` on the `IntersectionObserver` instance.\n\n```cs\nobserver.Dispose();\n```\n\nThis is a useful method to clean up observers when components are disposed of, i.e.\n\n```razor\n@using Ljbc1994.Blazor.IntersectionObserver\n@implements IAsyncDisposable\n@inject IIntersectionObserverService ObserverService\n\n\u003cdiv @ref=\"ImageRef\"\u003e\u003c/div\u003e\n\n@functions {\n    private IntersectionObserver Observer;\n    @* Code... *@\n\n    public async ValueTask DisposeAsync()\n    {\n        if (this.Observer != null)\n        {\n            await this.Observer.Dispose();\n        }\n    }\n}\n\n```\n\n### Component\n\n#### `\u003cIntersectionObserve\u003e`\n\nRather than directly interfacing with the service, you can use this convenience component for quick and easy observing. You can access the observer entry through the implicit `@context`!\n\nYou need to make sure to provide the reference of the element you want to observe, this is done by passing the element reference to the context reference.\n\n```razor\n@* Injecting service... *@\n\n\u003cIntersectionObserve\u003e\n    \u003cdiv @ref=\"context.Ref.Current\"\u003e\n        Hey... look I'm @(context.IsIntersecting ? \"intersecting!\": \"not intersecting!\")\n    \u003c/div\u003e\n\u003c/IntersectionObserve\u003e\n\n@* Component code... *@\n```\n\n##### Props\n\n- `OnChange` (`EventCallback\u003cIntersectionObserverEntry\u003e`) - When the intersection observer has a entry update.  \n- `IsIntersecting` (`bool`) - Whether the element is intersecting - used for two-way binding.\n- `Options` (`IntersectionObserverOptions`) - The options for the observer.\n- `Once` (`bool`) - Only observe once for an intersection, then the instance disposes of itself.\n\n#### Context \nThe context is the `IntersectionObserverContext` object, with the following signature:\n\n```cs\npublic class IntersectionObserverContext \n{\n    public IntersectionObserverEntry Entry { get; set; }\n    public ForwardReference Ref { get; set; } = new ForwardReference();\n    public bool IsIntersecting =\u003e this.Entry?.IsIntersecting ?? false;\n}\n\npublic class IntersectionObserverEntry\n{\n    public bool IsIntersecting { get; set; }\n\n    public double IntersectionRatio { get; set; }\n\n    public DOMRectReadOnly BoundingClientRect { get; set; }\n\n    public DOMRectReadOnly RootBounds { get; set; }\n\n    public bool IsVisible { get; set; }\n\n    public double Time { get; set; }\n}\n```\n\n## Additional Information\n\n### Upgrading to `2.0.1`+\n\nIn versions prior to `2.0.1`, the `IntersectionObserve` component didn't require a reference to the node as it was wrapped in an element that was automatically observed. This was changed to ensure the consumer provides the reference to prevent any potential layout issues and make it explicit what element should be observed.\n\nTherefore, before `2.0.1`, if the consumer had an element with `display: none;` within the `IntersectionObserve` component, this would have worked. However, as we're now observing the element provided as opposed to a wrapped element, this will no longer work. To resolve this, you can wrap the observed element in a div and observe the container div instead of the observed element.\n\n## Feature Requests\nThere's so much that `IntersectionObserver` can do, so if you have any requests or you want better documentation and examples, feel free to make a pull request or create an issue!\n\n\n\n\n\n\n","funding_links":[],"categories":["Libraries \u0026 Extensions"],"sub_categories":["Tools \u0026 Utilities","2D/3D Rendering engines"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fljbc1994%2FBlazorIntersectionObserver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fljbc1994%2FBlazorIntersectionObserver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fljbc1994%2FBlazorIntersectionObserver/lists"}