LexiFi / ocaml-vdom

Elm architecture and (V)DOM for OCaml
MIT License
197 stars 13 forks source link

Nested elements block onclick events #18

Closed leviroth closed 6 years ago

leviroth commented 6 years ago

Example code:

open Vdom

type model = Unclicked | Clicked

type message = Click

let view =
  function
  | Unclicked ->
    div ~a:[onclick Click; class_ "outer"]
      [div ~a:[ class_ "inner"] [text "inside the inner div"]; text "outside the inner div"]
  | Clicked ->
    div [text "Clicked"]

let init = Unclicked

let update m =
  function
  | Click -> Clicked

let app = simple_app ~init ~view ~update ()

let run () =
  Vdom_blit.run app
  |> Vdom_blit.dom
  |> Js_browser.Element.append_child (Js_browser.Document.body Js_browser.document)

let () =
  Js_browser.Window.set_onload Js_browser.window run

In the resulting app, clicking in the inner div doesn't do anything, seemingly because the inner div has its own do-nothing onclick handler that's capturing the event. Is this the intended behavior? It doesn't work that way when I try implementing the same thing in JavaScript, but that might be my limited knowledge of JavaScript and the DOM.

alainfrisch commented 6 years ago

This might qualify as a bug indeed. The current implementation relies on propagation: it attaches genric event listeners only to the toplevel container for the app, and those generic handlers finds the actual callback depending on the event target (walking the vdom). But it only looks for callbacks on the innermost element, and it should emulate the usual propagation itself (i.e. fallback to looking on its ancestors, up to the root of the app).

alainfrisch commented 6 years ago

19 fixes the reported case. Can you check that it works for you real application (assuming you find the problem on a larger example)?

leviroth commented 6 years ago

Confirmed.

alainfrisch commented 6 years ago

Thanks!