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

No way to stop event bubling. #2044

Closed
1 of 3 tasks
Madoshakalaka opened this issue Sep 11, 2021 · 3 comments
Closed
1 of 3 tasks

No way to stop event bubling. #2044

Madoshakalaka opened this issue Sep 11, 2021 · 3 comments
Labels

Comments

@Madoshakalaka
Copy link
Contributor

Problem

Before 68d2fdb, Event::stop_propogation works inside Callbacks. After that, bubbling is always enabled, even if stop_propagation is called, the ancestor's callback will still gets called.

Steps To Reproduce

minimal testing code:

use yew::prelude::*;

struct Model;

impl Component for Model {
    type Message = ();
    type Properties = ();

    fn create(ctx: &Context<Self>) -> Self {
        Self
    }

    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
        false
    }


    fn view(&self, ctx: &Context<Self>) -> Html {

        let parent_onclick = ctx.link().callback(|_|{
            gloo_console::info!("Parent callback!");
        });

        let child_onclick = ctx.link().callback(|e: MouseEvent|{
            gloo_console::info!("Child callback!");
            e.stop_propagation();
        });

        html! {
        <div style="height: 80px; width:80px; background-color: blue;" onclick={parent_onclick}>
            <div style="height: 40px; width:40px; background-color: green;" onclick={child_onclick}/>
        </div>
        }
    }
}

fn main() {
    yew::start_app::<Model>();
}

Click on the child, and the parent's callback gets called despite there is a stop_propogation.

Expected behavior

stop_propogation should stop the bubbling.

Environment:

  • Yew version: [master]
  • Rust version: [1.55.0]

Questionnaire

  • I'm interested in fixing this myself but don't know where to start
  • I would like to fix and I have a solution
  • I don't have time to fix this right now, but maybe later
@mc1098
Copy link
Contributor

mc1098 commented Sep 11, 2021

#1542 registers all event handlers on to the body element and then Yew performs the event bubbling based on the event target. #1542 introduced a global switch to enable or disable bubbling on events but this is global and doesn't stop bubbling at a specific point in the tree traversal but stops it happening at all.

#1542 added some comments regarding this issue:

/// Set, if events should bubble up the DOM tree, calling any matching callbacks.
///
/// Bubbling is enabled by default. Disabling bubbling can lead to substantial improvements in event
/// handling performance.
///
/// Note that yew uses event delegation and implements internal even bubbling for performance
/// reasons. Calling `Event.stopPropagation()` or `Event.stopImmediatePropagation()` in the event
/// handler has no effect.
///
/// This function should be called before any component is mounted.
pub fn set_event_bubbling(bubble: bool) {
// XXX: we have no way to detect, if the callback called `Event.stopPropagation()`
// or `Event.stopImmediatePropagation()` without breaking the callback API.
// It's arguably not worth the cost.

This comment in the PR suggests that Yew could stop bubbling using Event::cancel_bubble and the behaviour is defined in the WHATWG living standard so I think we are okay in terms of compatibility to use this.

@Madoshakalaka
Copy link
Contributor Author

@mc1098 Thanks for your help! it's not a bug but an expected behavior then. We definitely need a documentation section on bubbling and introduce pub fn set_event_bubbling as an alternative to stopPropogation

@mc1098
Copy link
Contributor

mc1098 commented Sep 12, 2021

We definitely need a documentation section on bubbling

Agreed, I didn't add this to the event page but I think that's the best home for it!

pub fn set_event_bubbling as an alternative to stopPropogation

I don't think it particularly is because it will prevent event bubbling for every event handler unless changed back, whereas stop_propagation is specific to the event it's applied to. I guess this depends on the use case, if you never want event bubbling this is a nice global flag to set with a good performance boost.

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

No branches or pull requests

2 participants