Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Click outside event? #3012

Closed
lcswillems opened this issue Jun 11, 2019 · 12 comments
Closed

Click outside event? #3012

lcswillems opened this issue Jun 11, 2019 · 12 comments

Comments

@lcswillems
Copy link

Hi,

Is there a click outside event available?

@andymans
Copy link

If I recall, in Svelte 2 there was one (was something like off:xyz={} The docs for Svelte 3 are less user-friendly, and if this feature exists, it's not mentioned in them.

@lcswillems
Copy link
Author

Okay, thank you for the answer.

@andymans
Copy link

Sadly the old docs (which were at http://svelte.technology) are no longer available as that address now points to the new stuff. I'm going to grab 'em using the wayback machine (<--cannot believe that I've just written this in the age of ubiquitous version control!!)

@Conduitry
Copy link
Member

Conduitry commented Jun 12, 2019

The old docs are available at https://v2.svelte.dev/

There is not and never was an event for clicking outside of a given element. Svelte's element events use actual DOM events, and there isn't one for clicking outside an element. You would typically attach an event handler to the entire window and check whether the target is contained within the element in question.

@lcswillems
Copy link
Author

Okay, thank you for all the answers!

@CanRau
Copy link

CanRau commented Nov 7, 2019

Haven't tried it yet but for future reference there's svelte-click-outside

@cbenz
Copy link

cbenz commented Apr 24, 2020

I prefer this implementation which uses a Svelte action (<div use:clickOutside={handleClickEvent}>) because it does not require adding an extra <div>.

https://github.com/rster2002/svelte-outside-click

There is also this REPL example: https://svelte.dev/repl/0ace7a508bd843b798ae599940a91783?version=3.16.7 (I can't find the original author).

@babakfp
Copy link
Contributor

babakfp commented Oct 14, 2021

Hi
Check out this repo for Svelte on:clickOutside event:
https://github.com/babakfp/svelte-click-outside
It has an array to exclude elements from the event and a class prop to style the wrapper element.

@dayvista
Copy link

dayvista commented Sep 3, 2022

For those using the solution from @cbenz with SvelteKit and TypeScript, add this to the global.d.ts file in the src folder:

declare namespace svelte.JSX {
	interface HTMLAttributes<T> {
		onclick_outside?: (e: CustomEvent) => void
	}
}

(found in this StackOverflow answer)

@jdgamble555
Copy link

Here is the TS version, I hope they make Svelte REPL support TS in the future!

export function clickOutside(node: HTMLElement, ignore?: string) {

    const handleClick = (event: Event) => {
        const target = event.target as HTMLElement;
        if (!event.target || ignore && target.closest(ignore)) {
            return;
        }
        if (node && !node.contains(target) && !event.defaultPrevented) {
            node.dispatchEvent(
                new CustomEvent('click_outside')
            );
        }
    }

    document.addEventListener('click', handleClick, true);

    return {
        destroy() {
            document.removeEventListener('click', handleClick, true);
        }
    };
};

I also made a little secondary option in case you want to ignore a certain element that is outside. This came in handle for me when I clicked the same button twice.

use:clickOutside={'#user-menu-button'}
on:click_outside={profileDropdown.close}

J

@vnphanquang
Copy link

For others coming to this thread, especially typescript users, i abstracted this with a svelte action into @svelte-put/clickoutside. Hope that helps.

@m-poh
Copy link

m-poh commented Jan 15, 2024

I am working with custom components and was using the solution provided by @jdgamble555 . while using the ignore parameter, i ran into an issue that i was ignoring an element which was inside the custom element and so the event.target was the custom element itself. i solved it with replacing the

const target = event.target as HTMLElement

with

const path = e.composedPath()
const target = path[0] as HTMLElement

this works with clicks from within the element and from outside. are there any issues with this solution?

Dilden added a commit to Dilden/helth that referenced this issue Jan 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants