Skip to content

feat: add support of handleEvent object listener #15856

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

7nik
Copy link
Contributor

@7nik 7nik commented Apr 30, 2025

Closes #8196

The type of on:event on components is still function only, though it works with the object handler. Not sure where to fix it.

In the following case, it can be considered kind of a breaking change:

const props: HTMLAttributes = $props();
// later
props.onclick(); // will error when `onclick` is an object handler

someFnAcceptingCallback(props.onclick); // same problem

and any other place where the event handler is expected to be function only.

Also, the handler object seems to never get hoisted.

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.
  • If this PR changes code within packages/svelte/src, add a changeset (npx changeset).

Tests and linting

  • Run the tests with pnpm test and lint the project with pnpm lint

Copy link

changeset-bot bot commented Apr 30, 2025

🦋 Changeset detected

Latest commit: c5b92b1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

Playground

pnpm add https://pkg.pr.new/svelte@15856

@ottomated
Copy link
Contributor

Is this worth adding? It seems like it's a non-zero amount of complexity and overhead for a basically useless feature, but if there's a legitimate use for handleEvent objects I suppose it could make sense to match the DOM spec

@Ocean-OS
Copy link
Contributor

Ocean-OS commented May 4, 2025

Is this worth adding? It seems like it's a non-zero amount of complexity and overhead for a basically useless feature, but if there's a legitimate use for handleEvent objects I suppose it could make sense to match the DOM spec

I've been using this feature for a little while and have found it quite useful. Here's the article through which I found out about it, it's pretty interesting

@svelte-docs-bot
Copy link

@7nik
Copy link
Contributor Author

7nik commented May 11, 2025

Oh, somehow I've missed that this should be the object but not the element.

@Rich-Harris
Copy link
Member

I'm also unclear on the real world benefit of this, can someone ELI5? I'm familiar with Andrea's article and I can't quite wrap my head around where it would be useful (though I do find myself wondering if we could take advantage of this approach internally instead of using delegation)

@Ocean-OS
Copy link
Contributor

I'm also unclear on the real world benefit of this, can someone ELI5?

  1. If you have an event handler(s) that you want to remove, it makes it a lot easier
  2. A way to unify all event handlers that could be related to each other
  3. Devs coming from vanilla JS might want to use it

though I do find myself wondering if we could take advantage of this approach internally instead of using delegation

I was actually thinking of making a PR that would do that, should I start working on it?

@Rich-Harris
Copy link
Member

  1. If you have an event handler(s) that you want to remove, it makes it a lot easier

How so? Is handler.handleEvent = null easier than handler = null?

  1. A way to unify all event handlers that could be related to each other

Is it easier than doing this?

<script>
  const handlers = {
    onmouseenter() {
      console.log('enter');
    },
    onmouseleave() {
      console.log('leave');
    }
  };
</script>

<div {...handlers}></div>

What would it look like — this?

<script>
  const handler = {
    handleEvent(e) {
      this['on' + e.type]?.(e);
    },
    onmouseenter() {
      console.log('enter');
    },
    onmouseleave() {
      console.log('leave');
    }
  };
</script>

<div onmouseenter={handler} onmouseleave={handler}></div>

It doesn't seem like an improvement. Maybe I'm missing something but I'm struggling to come up with a scenario where it's helpful.

  1. Devs coming from vanilla JS might want to use it

Aside from #8196 no-one has ever asked for it, so it feels like YAGNI to me.

I was actually thinking of making a PR that would do that, should I start working on it?

As long as you're at peace with the possibility that it wouldn't get merged 😅 it would have to have the same-or-better performance/memory characteristics, and not having any breaking changes in terms of timing etc. (It's possible that we'd actually be able to improve the timing situation, since handlers manually added with addEventListener would presumably no longer run in a distinct phase, but if that's considered a breaking change then this might have to wait until Svelte 6.)

@7nik
Copy link
Contributor Author

7nik commented May 14, 2025

I just looked at Solid's implementation and they also allow passing listener options on the object. Interesting idea. Though, they did it mostly to support adding listeners with the capture/passive/once options declaratively in the markup.

@7nik
Copy link
Contributor Author

7nik commented May 14, 2025

I did it just because the issue has the PRs welcome label 😄

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

Successfully merging this pull request may close these issues.

addEventListener, object with a handleEvent() method support.
4 participants