diff --git a/packages/web/src/dom.rs b/packages/web/src/dom.rs index 20119dd25..b25b7826c 100644 --- a/packages/web/src/dom.rs +++ b/packages/web/src/dom.rs @@ -380,22 +380,38 @@ extern "C" { } fn walk_event_for_id(event: &web_sys::Event) -> Option<(ElementId, web_sys::Element)> { - let mut target = event + let target = event .target() .expect("missing target") - .dyn_into::() - .expect("not a valid element"); + .dyn_into::() + .expect("not a valid node"); + let mut current_target_element = target.dyn_ref::().cloned(); loop { - match target.get_attribute("data-dioxus-id").map(|f| f.parse()) { - Some(Ok(id)) => return Some((ElementId(id), target)), - Some(Err(_)) => return None, + match ( + current_target_element + .as_ref() + .and_then(|el| el.get_attribute("data-dioxus-id").map(|f| f.parse())), + current_target_element, + ) { + // This node is an element, and has a dioxus id, so we can stop walking + (Some(Ok(id)), Some(target)) => return Some((ElementId(id), target)), - // walk the tree upwards until we actually find an event target - None => match target.parent_element() { - Some(parent) => target = parent, - None => return None, - }, + // Walk the tree upwards until we actually find an event target + (None, target_element) => { + let parent = match target_element.as_ref() { + Some(el) => el.parent_element(), + // if this is the first node and not an element, we need to get the parent from the target node + None => target.parent_element(), + }; + match parent { + Some(parent) => current_target_element = Some(parent), + _ => return None, + } + } + + // This node is an element with an invalid dioxus id, give up + _ => return None, } } }