How to stop <li> onclick bubble-up...?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Joakim Braun

    How to stop <li> onclick bubble-up...?

    I'd like to show tree structures using collapsible multi-level nested <ul>
    lists (with open/closed "disclosure triangles" as list-style-images).
    Something like this:

    <ul>
    <li onclick="alert( 'Level 1 clicked');">Lev el 1
    <ul>
    <li onclick="alert( 'Level 2 clicked');">Lev el 2
    </li>
    </ul>
    </li>
    </ul>

    Clicking on the text following <li> (or on the list-style-image)
    collapses/expands the rest of the content of that <li> (not shown here).

    The problem is that each click bubbles up to the topmost list item. That is,
    a click on "Level 2" first executes the innermost <li> onclick handler, then
    the one for the next-outer-level <li> and so on. How can I make it so that
    only the handler for the <li> that's clicked is executed? (returning false
    from onclick didn't help in IE 6)

    (I know I could wrap the text in <span>s and add the onclick handlers to
    those instead, but that's a bit ugly, and the list-style-image would be out
    of action)

    Joakim Braun



  • Michael Winter

    #2
    Re: How to stop &lt;li&gt; onclick bubble-up...?

    On Tue, 7 Dec 2004 20:37:26 +0100, Joakim Braun
    <joakim.braun@j fbraun.removeth is.com> wrote:

    [snip]
    [color=blue]
    > The problem is that each click bubbles up to the topmost list item.
    > [...] How can I make it so that only the handler for the <li> that's
    > clicked is executed?[/color]

    You should be able to stop propagation with

    if(evt.stopProp agation) {evt.stopPropag ation();}
    evt.cancelBubbl e = true;

    It's not going to work with NN4, though it should with IE4.

    An alternative solution that would work in other situations (but not this
    one) is to check the origin of the event. If it matched the current
    element, you know you act on that event. If it didn't, ignore the event.
    It is possible to see if the target is an immediate child, but I such a
    solution would be more likely to work in more browsers than the one above
    (I could be wrong, though).
    [color=blue]
    > (returning false from onclick didn't help in IE 6)[/color]

    Returning false may cancel the action of that event, but it won't stop it
    propagating.

    [snip]

    Mike

    --
    Michael Winter
    Replace ".invalid" with ".uk" to reply by e-mail.

    Comment

    • Joakim Braun

      #3
      Re: How to stop &lt;li&gt; onclick bubble-up...?

      "Michael Winter" <M.Winter@bluey onder.co.invali d> skrev i meddelandet
      news:opsinmw206 x13kvk@atlantis ...[color=blue]
      > On Tue, 7 Dec 2004 20:37:26 +0100, Joakim Braun
      > <joakim.braun@j fbraun.removeth is.com> wrote:
      >
      > [snip]
      >[color=green]
      > > The problem is that each click bubbles up to the topmost list item.
      > > [...] How can I make it so that only the handler for the <li> that's
      > > clicked is executed?[/color]
      >
      > You should be able to stop propagation with
      >
      > if(evt.stopProp agation) {evt.stopPropag ation();}
      > evt.cancelBubbl e = true;
      >
      > It's not going to work with NN4, though it should with IE4.[/color]
      <snip>

      Thanks, that was helpful. Now to see what Opera says...

      (tried tables before, but the non-nestability of <tbody>s (and consequent
      use of subtables with multiple spacer columns for indentation) seemed too
      hacky)

      Joakim Braun


      Comment

      • Michael Winter

        #4
        Re: How to stop &lt;li&gt; onclick bubble-up...?

        On Tue, 7 Dec 2004 21:52:49 +0100, Joakim Braun
        <joakim.braun@j fbraun.removeth is.com> wrote:
        [color=blue]
        > "Michael Winter" <M.Winter@bluey onder.co.invali d> skrev i meddelandet
        > news:opsinmw206 x13kvk@atlantis ...[/color]

        [snip]
        [color=blue][color=green]
        >> if(evt.stopProp agation) {evt.stopPropag ation();}
        >> evt.cancelBubbl e = true;[/color][/color]

        [snip]
        [color=blue]
        > Thanks, that was helpful. Now to see what Opera says...[/color]

        Opera supports the DOM Events module, so you'll have no problems there.
        Any recent DOM-conforming browser should execute the Event.stopPropa gation
        method. IE is the reason for the second line.

        [snip]

        Mike

        --
        Michael Winter
        Replace ".invalid" with ".uk" to reply by e-mail.

        Comment

        • Rob B

          #5
          Re: How to stop &lt;li&gt; onclick bubble-up...?

          Joakim Braun wrote:
          [color=blue]
          > I'd like to show tree structures using collapsible multi-level nested[/color]
          <ul>[color=blue]
          > lists (with open/closed "disclosure triangles" as list-style-images).
          > Something like this:[/color]
          [color=blue]
          > <ul>
          > <li onclick="alert( 'Level 1 clicked');">Lev el 1
          > <ul>
          > <li onclick="alert( 'Level 2 clicked');">Lev el 2
          > </li>
          > </ul>
          > </li>
          > </ul>[/color]
          [color=blue]
          > Clicking on the text following <li> (or on the list-style-image)
          > collapses/expands the rest of the content of that <li> (not shown[/color]
          here).

          (snip)

          Could always use bubbling to your advantage, by processing click events
          at a higher level.

          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
          <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
          <head>
          <title>feh!</title>
          <style type="text/css">

          .there { display: block; }
          .nowhere { display: none; }

          </style>
          <script type="text/javascript">
          //<![CDATA[

          function process(e)
          {
          e = e || (window.event || {});
          var el, tgt = e.srcElement || e.target;
          if (tgt && (el = tgt.getElements ByTagName('ul') .item(0)))
          el.className = 'therenowhere'. replace(el.clas sName, '');
          }

          onload = function()
          {
          document.getEle mentsByTagName( 'body').item(0) .onclick = process;
          }

          //]]>
          </script>
          </head>
          <body>
          <ul>
          <li>Level 1
          <ul class="nowhere" >
          <li>Level 2
          <ul class="nowhere" >
          <li>Level 3
          </li>
          </li>
          </ul>
          </li>
          </ul>
          </body>
          </html>

          Barely a demo.

          *** Sent via Developersdex http://www.developersdex.com ***
          Don't just participate in USENET...get rewarded for it!

          Comment

          • Joakim Braun

            #6
            Re: How to stop &lt;li&gt; onclick bubble-up...?

            "Rob B" <ferndoc9@hotma il.com> skrev i meddelandet
            news:1102455247 .9542512efc4f61 acd5d7362393ae8 aed@teranews...
            <snip>[color=blue]
            > Could always use bubbling to your advantage, by processing click events
            > at a higher level.
            >
            > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
            > "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
            > <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
            > <head>
            > <title>feh!</title>
            > <style type="text/css">
            >
            > there { display: block; }
            > nowhere { display: none; }
            >
            > </style>
            > <script type="text/javascript">
            > //<![CDATA[
            >
            > function process(e)
            > {
            > e = e || (window.event || {});
            > var el, tgt = e.srcElement || e.target;
            > if (tgt && (el = tgt.getElements ByTagName('ul') .item(0)))
            > el.className = 'therenowhere'. replace(el.clas sName, '');
            > }
            >
            > onload = function()
            > {
            > document.getEle mentsByTagName( 'body').item(0) .onclick = process;
            > }
            >
            > //]]>
            > </script>
            > </head>
            > <body>
            > <ul>
            > <li>Level 1
            > <ul class="nowhere" >
            > <li>Level 2
            > <ul class="nowhere" >
            > <li>Level 3
            > </li>
            > </li>
            > </ul>
            > </li>
            > </ul>
            > </body>
            > </html>[/color]

            How cute - no JS handlers at all in the source code. I'll remember that one.

            Joakim Braun


            Comment

            Working...