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

wrong event callback ordering on first event handler #2409

Open
MartinWelsch opened this issue Mar 6, 2024 · 3 comments
Open

wrong event callback ordering on first event handler #2409

MartinWelsch opened this issue Mar 6, 2024 · 3 comments
Labels
documentation Improvements or additions to documentation

Comments

@MartinWelsch
Copy link

Describe the bug
The call order of events for the first event handler on an element with respect to window is incorrect and does not follow the bubbling rules for events.

The bubbling order is (for example a button and the pointerdown event): button -> parent -> window

But the current version calls the event handlers in the order window -> button -> parent for the first event handler appearing in the call tree.
All following event handlers are called in the correct order.

Leptos Dependencies

leptos = { version = "0.6.6", features = ["nightly", "csr"] }
console_log = "0.2"
log = "0.4"
console_error_panic_hook = "0.1.7"
leptos-use = "0.10.4"

For example:
Given the following code (also found here)

use leptos::*;
use leptos_use::*;

#[component]
pub fn Comp1() -> impl IntoView {
    let (last_call, set_last_call) = create_signal("none".to_string());

    _ = use_event_listener(use_window(), leptos::ev::pointerdown, move |ev| {
        set_last_call.update(|v| v.push_str(" window"));
    });

    view! {
        <div on:pointerdown=move |_| set_last_call.update(|v| v.push_str(" parent"))>
            <span>{ move || last_call() }</span>
            <button on:pointerdown=move |_| set_last_call.update(|v| v.push_str(" button"))>{"CLICK"}</button>
        </div>
    }
}

pub fn main() {
    mount_to_body(|| {
        view! {
            <div style="display: flex; flex-direction: column;"
                // uncomment following line to fix behavior
                // on:pointerdown=|_|{}
                >
                <Comp1 />
                <Comp1 />
                <Comp1 />
                <Comp1 />
            </div>
        }
    })
}

When clicking any button labeled CLICK, the text line next to the button should get appended by button parent window (which is the expected call order explained above)
The other text lines just get appended by window because the event handler on window is the only one called for this component.

To Reproduce
Steps to reproduce the behavior:

  1. Click the topmost button and observe the last 3 appended words which are window button parent (wrong order)
  2. Click any other button and observe the last 3 appended words which are button parent window (right order)

Expected behavior

Expected the first button press to behave just like the other ones: produce the text sequence button parent window

@gbj
Copy link
Collaborator

gbj commented Mar 6, 2024

I'm not sure about the distinction between "first in the tree" and the rest. I can say that events are delegated to the window by default, and that you can opt out by adding :undelegated, so for example on:pointerdown:undelegated=move |_| etc.

@MartinWelsch
Copy link
Author

:undelegated does indeed fix the behavior for the first event listener. It also fixes not being able to stop_propagation() on the event (without :undelegated the event handler on window is called regardless if stop_propagation() is called or not).

Is there some documentation on :undelegated? I could not find any.

So i guess this is intended (or more undefined) behavior when mixing DOM event handlers and leptos event handlers without :undelegated?

@gbj gbj added the documentation Improvements or additions to documentation label Mar 18, 2024
@gbj
Copy link
Collaborator

gbj commented Mar 18, 2024

Documenting :undelegated more clearly is definitely in the backlog of docs to be written. It is just the syntax in the view macro for adding undelegated to an event listener, but the docs that need to be added are more in the category of "when would you want to do this?"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

2 participants