clicking on list elements - problem

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

    clicking on list elements - problem

    Hi all.

    My list:

    <ul>
    <li id="a" onclick="show(t his)">Aaaaaaaa</li>
    <li id="b" onclick="show(t his)">Bbbbbbbb</li>
    <li id="c" onclick="show(t his)">Cccccccc
    <ul>
    <li id="d" onclick="show(t his)">111111</li>
    <li id="e" onclick="show(t his)">222222</li>
    <li id="f" onclick="show(t his)">333333
    <ul>
    <li id="g" onclick="show(t his)">@@@@@@@@@ </li>
    <li id="h" onclick="show(t his)">{{{{{{{}</li>
    <li id="i" onclick="show(t his)">????>>>>> </li>
    </ul>
    </li>
    </ul>
    </li>
    </ul>

    <ul>
    <li id="j" onclick="show(t his)">qqq</li>
    <li id="k" onclick="show(t his)">vvvv</li>
    </ul>

    And function:

    function show(clicked)
    {
    alert(clicked.i d)
    }

    The trouble is that when I click on the list element having id="g", there
    appear three alerts one by one showing "g", then "f", and "c". Prabably
    that's because those element are nested. How could I prevent showing the id
    of clicked element and its parents ? I'd like only clicked element's id to
    be showed.

    Best regards,
    ABS


  • VK

    #2
    Re: clicking on list elements - problem

    The best trick for all this event mess so far I found is from Lasse
    Reichstein Nielsen:
    ....
    <li id="i" onclick="show(t his, (event.target|| event.srcElemen t))">Some
    text­</li>
    ....

    function show(src,trg) {
    if (src == trg) {
    alert(src.id);
    }
    }

    Works for IE 6.x and FF 1.0.3/4

    Comment

    • abs

      #3
      Re: clicking on list elements - problem

      > The best trick for all this event mess so far I found is from Lasse[color=blue]
      > Reichstein Nielsen: [...][/color]

      That works ! Thank you !

      ABS


      Comment

      • RobB

        #4
        Re: clicking on list elements - problem

        abs wrote:[color=blue]
        > Hi all.
        >
        > My list:
        >
        > <ul>
        > <li id="a" onclick="show(t his)">Aaaaaaaa</li>
        > <li id="b" onclick="show(t his)">Bbbbbbbb</li>
        > <li id="c" onclick="show(t his)">Cccccccc
        > <ul>
        > <li id="d" onclick="show(t his)">111111</li>
        > <li id="e" onclick="show(t his)">222222</li>
        > <li id="f" onclick="show(t his)">333333
        > <ul>
        > <li id="g" onclick="show(t his)">@@@@@@@@@ </li>
        > <li id="h" onclick="show(t his)">{{{{{{{}</li>
        > <li id="i" onclick="show(t his)">????>>>>> </li>
        > </ul>
        > </li>
        > </ul>
        > </li>
        > </ul>
        >
        > <ul>
        > <li id="j" onclick="show(t his)">qqq</li>
        > <li id="k" onclick="show(t his)">vvvv</li>
        > </ul>
        >
        > And function:
        >
        > function show(clicked)
        > {
        > alert(clicked.i d)
        > }
        >
        > The trouble is that when I click on the list element having id="g",[/color]
        there[color=blue]
        > appear three alerts one by one showing "g", then "f", and "c".[/color]
        Prabably[color=blue]
        > that's because those element are nested. How could I prevent showing[/color]
        the id[color=blue]
        > of clicked element and its parents ? I'd like only clicked element's[/color]
        id to[color=blue]
        > be showed.
        >
        > Best regards,
        > ABS[/color]

        Might want to consider a more global approach to handling those
        clicks...

        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">
        <html>
        <head>
        <style type="text/css">

        li {
        background: #ddd;
        margin: 2px 0;
        cursor: pointer;
        }

        </style>
        <script type="text/javascript">

        document.onclic k = function(e)
        {
        var tgt;
        if ((e = e || window.event)
        && (tgt = e.srcElement || e.target)
        && /LI/i.test(tgt.node Name))
        {
        alert(tgt.id);
        }
        }

        </script>
        </head>
        <body>
        <ul>
        <li id="a">Aaaaaaaa </li>
        <li id="b">Bbbbbbbb </li>
        <li id="c">Ccccccc c
        <ul>
        <li id="d">111111</li>
        <li id="e">222222</li>
        <li id="f">333333
        <ul>
        <li id="g">@@@@@@@@ @</li>
        <li id="h">{{{{{{{} </li>
        <li id="i">????>>>> ></li>
        </ul>
        </li>
        </ul>
        </li>
        </ul>
        <ul>
        <li id="j">qqq</li>
        <li id="k">vvvv</li>
        </ul>
        </body>
        </html>

        Comment

        • abs

          #5
          Re: clicking on list elements - problem

          abs wrote:[color=blue]
          > That works ! Thank you ![/color]

          But there'e one problem. When I add onclick to element like this:

          liElement.oncli ck = function(){show (this, (event.target|| event.srcElemen t))}

          If then I click the element, Firefox claims: "Error: event is not defined".
          But when I define onclick inline, like here

          <li id="i" onclick="show(t his,
          (event.target|| event.srcElemen t))">Sometext­ </li>

          everything's fine with click and works. So, what's the difference and
          where's the problem ?

          ABS


          Comment

          • abs

            #6
            Re: clicking on list elements - problem

            RobB wrote:[color=blue]
            > Might want to consider a more global approach to handling those
            > clicks... [...][/color]

            Thank you. That helped a lot.

            Regards,
            ABS


            Comment

            • RobB

              #7
              Re: clicking on list elements - problem

              abs wrote:[color=blue]
              > abs wrote:[color=green]
              > > That works ! Thank you ![/color]
              >
              > But there'e one problem. When I add onclick to element like this:
              >
              > liElement.oncli ck = function(){show (this,[/color]
              (event.target|| event.srcElemen t))}[color=blue]
              >
              > If then I click the element, Firefox claims: "Error: event is not[/color]
              defined".[color=blue]
              > But when I define onclick inline, like here
              >
              > <li id="i" onclick="show(t his,
              > (event.target|| event.srcElemen t))">Sometext­ </li>
              >
              > everything's fine with click and works. So, what's the difference and
              > where's the problem ?
              >
              > ABS[/color]

              Glad to hear it. Try...

              liElement.oncli ck = function(e){sho w(this, (e.target||e.sr cElement))}

              When you register a handler programmaticall y (JS) the mozilla Event
              object is automatically passed to your handler as arguments[0]. You
              need to catch it at the other end, even if the handler is a wrapper (as
              above). Handlers assigned in HTML are wrapped automatically and the
              Event object is exposed as the local variable 'event'.

              Comment

              • RobB

                #8
                Re: clicking on list elements - problem

                Oops, cross-browser...

                liElement.oncli ck = function(e)
                {
                if (!e) e = window.event;
                show(this, (e.target||e.sr cElement))
                }

                Comment

                • RobB

                  #9
                  Re: clicking on list elements - problem

                  Leisure reading: #;=)



                  Comment

                  • Michael Winter

                    #10
                    Re: clicking on list elements - problem

                    abs wrote:
                    [color=blue]
                    > But there'e one problem. [...]
                    >
                    > liElement.oncli ck = function(){show (this,
                    > (event.target|| event.srcElemen t))}[/color]

                    The IE event model differs from that used by most user agents, and the one
                    defined by the W3C. IE uses a global object called event to communicate
                    event-related information, whereas the W3C/Netscape model passes the event
                    object to listeners as an argument.

                    When a user agent encounters an intrinsic event in markup, it creates an
                    anonymous function that contains the code. Here, again, we find
                    differences.

                    When parsing

                    <element on<type>="/* User code */">

                    IE produces an intrinsic event listener like:

                    element.on<type > = function() {
                    /* User code */
                    };

                    This is fine because the event object is global in IE (and any user agents
                    that choose to follow it), so it can still be accessed. However, user
                    agents that follow the Netscape/W3C event model internally produce
                    intrinsic event listeners like:

                    element.on<type > = function(event) {
                    /* User code */
                    };

                    That is, they pass a reference to the event object with the identifier,
                    'event', to listeners. In your code, you don't try to access this argument,
                    so Firefox and others will not find an event object.

                    Change your code to:

                    liElement.oncli ck = function(e) {
                    e = e || event; /* Use either the argument, if supplied,
                    * or the global object.
                    */
                    show(this, e.target || e.srcElement);
                    };

                    [snip]

                    There is one potential problem: your code will only work if the target
                    element is what you expect. If you have any other elements within the list
                    item, the target is likely to be one of those elements. Just keep that in
                    mind.

                    Mike

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

                    Comment

                    • VK

                      #11
                      Re: clicking on list elements - problem

                      Here the better variant I have by now. I coming to the conclusion that
                      it's better don't use intristic event handlers in NN/FF, they are too
                      unstable.
                      It gives your more code in the <script> section, but you keep your <ul>
                      lists nice and clean. W3 should be happy: scripting, styling and
                      content are all separate and independent :-)

                      <html>
                      <head>
                      <title>UL's</title>
                      <meta http-equiv="Content-Type" content="text/html;
                      charset=iso-8859-1">
                      <script>
                      var isDOM = window.addEvent Listener;

                      function init() {
                      var foo = null;
                      var tmp = document.getEle mentsByTagName( 'LI');
                      for (i=0;i<tmp.leng th;i++) {
                      /* Add EventListener on the capturing phase
                      so we don't have to bother with bubbles history */
                      foo = (isDOM)?
                      tmp[i].addEventListen er('click',test ,true) :
                      tmp[i].attachEvent('o nclick',test);
                      }
                      }

                      function test(e) {
                      var tmp = '';
                      if (isDOM) {
                      e.stopPropagati on();
                      tmp = e.target.innerH TML;
                      }
                      else {
                      event.cancelBub ble = true;
                      tmp = event.srcElemen t.innerHTML;
                      }
                      alert(tmp);
                      }

                      window.onload = init;
                      </script>
                      </head>

                      <body bgcolor="#FFFFF F">
                      <ul>
                      <li>Level 1 - Item 1</li>
                      <li>Level 1 - Item 2
                      <ul>
                      <li>Level 2 - Item 1</li>
                      <li>Level 2 - Item 2
                      <ul>
                      <li>Level 3 - Item 1</li>
                      <li>Level 3 - Item 2</li>
                      <li>Level 3 - Item 3</li>
                      </ul>
                      </li>
                      <li>Level 2 - Item 3</li>
                      </ul>
                      </li>
                      <li>Level 1 - Item 3</li>
                      </ul>
                      </body>
                      </html>

                      Comment

                      • RobG

                        #12
                        Re: clicking on list elements - problem

                        VK wrote:[color=blue]
                        > Here the better variant I have by now. I coming to the conclusion that
                        > it's better don't use intristic event handlers in NN/FF, they are too
                        > unstable.[/color]

                        You have complained a number of times in recent posts about 'NN/FF',
                        but generally your discoveries have only shown the variances between IE
                        and Mozilla event models. That does not make Mozilla-based browsers
                        'unstable', it just means you have to take account of both event
                        models in your code.

                        Does adding an event handler dynamically avoid intrinsic events, or is
                        it just a different way of adding them?
                        [color=blue]
                        > It gives your more code in the <script> section, but you keep your <ul>
                        > lists nice and clean. W3 should be happy: scripting, styling and
                        > content are all separate and independent :-)
                        >
                        > <html>
                        > <head>
                        > <title>UL's</title>
                        > <meta http-equiv="Content-Type" content="text/html;
                        > charset=iso-8859-1">
                        > <script>
                        > var isDOM = window.addEvent Listener;
                        >
                        > function init() {
                        > var foo = null;
                        > var tmp = document.getEle mentsByTagName( 'LI');
                        > for (i=0;i<tmp.leng th;i++) {
                        > /* Add EventListener on the capturing phase
                        > so we don't have to bother with bubbles history */
                        > foo = (isDOM)?
                        > tmp[i].addEventListen er('click',test ,true) :
                        > tmp[i].attachEvent('o nclick',test);
                        > }
                        > }
                        >
                        > function test(e) {
                        > var tmp = '';
                        > if (isDOM) {
                        > e.stopPropagati on();
                        > tmp = e.target.innerH TML;
                        > }
                        > else {
                        > event.cancelBub ble = true;
                        > tmp = event.srcElemen t.innerHTML;
                        > }
                        > alert(tmp);
                        > }
                        >
                        > window.onload = init;
                        > </script>[/color]

                        To support older browsers, the following may suit:

                        function show(x) {
                        alert( (x.id || 'No id') + '\n' + x.innerHTML);
                        }


                        function init(){

                        if (document.getEl ementsByTagName ){
                        var lis = document.getEle mentsByTagName( 'LI');
                        } else if (document.all){
                        var lis = document.all.ta gs('LI');
                        } else {
                        return;
                        }

                        var i=lis.length;
                        while (i--){
                        lis[i].onclick = function(e) {
                        e = e || window.event;
                        e.cancelBubble = true;
                        if (e.stopPropagat ion) e.stopPropagati on();
                        show(this);
                        }
                        }
                        }



                        --
                        Rob

                        Comment

                        • VK

                          #13
                          Re: clicking on list elements - problem

                          > Does adding an event handler dynamically[color=blue]
                          > avoid intrinsic events, or is it just a different way of adding them?[/color]

                          Using intrinsic events forces you to use the non-documented EVENT
                          object in FF (Some people tried to say here that this is some special
                          EVENT and it has nothing to do by its nature with window.event in IE).

                          <html>
                          <head>
                          <title>Event</title>
                          <meta http-equiv="Content-Type" content="text/html;
                          charset=iso-8859-1">
                          </head>
                          <body>
                          <p onclick="alert( event.target)"> Test</p>
                          </body>
                          </html>

                          Click and get it. I did not create this EVENT object, nevertheless it's
                          available and self-updating. Thus it's a global public self-updating
                          event object. Thus it's equal to windows.event in IE. (By trying to
                          find some contextual differences we would have some religious
                          discussion here, sort of is Mary holy or is she just God's mother). But
                          Mozilla is dead silent about this object. They don't promise us any
                          properties or behaviours. So better use dynamic handlers. They are much
                          more flexible and in case if something doesn't work, we can always say
                          "hey, look what did you say and what do we have!".

                          Comment

                          • Andy LW

                            #14
                            Re: clicking on list elements - problem

                            "RobB" <ferndoc9@hotma il.com>, haber iletisinde sunlari
                            yazdi:111643515 7.414372.287890 @g14g2000cwa.go oglegroups.com. ..[color=blue]
                            > Leisure reading: #;=)
                            >
                            > http://www.onlinetools.org/articles/...ipt/index.html
                            >[/color]

                            could you please explain this line (or point to some online source that
                            could help me understand):

                            if ((e = e || window.event)
                            && (tgt = e.srcElement || e.target)
                            && /LI/i.test(tgt.node Name))

                            i sometimes come across with such beautiful techniques suggested by js
                            masters but none of the books i have includes them.


                            Comment

                            • Michael Winter

                              #15
                              Re: clicking on list elements - problem

                              VK wrote:
                              [color=blue]
                              > Using intrinsic events forces you to use the non-documented EVENT
                              > object in FF[/color]

                              Whilst I've never seen explicit documentation (more implication than
                              anything else), both Netscape's JavaScript Guide and Mozilla's DOM
                              Reference contain an example (different in each case) that uses the 'event'
                              identifier in the context of an intrinsic event attribute. In addition,
                              showing the string representation of an intrinsic event property clearly
                              reveals the presence of an argument named 'event'.

                              This behaviour is used by every scriptable user agent that follows the
                              Netscape event model that I've ever encountered. To dismiss overwhelming
                              empirical evidence just because Netscape didn't bother to state the
                              behaviour explicitly is quite ridiculous.
                              [color=blue]
                              > (Some people tried to say here that this is some special EVENT and it
                              > has nothing to do by its nature with window.event in IE).[/color]

                              They are common in that they both provide access to event-related
                              information. How they are provided is very different.

                              [snip]
                              [color=blue]
                              > <p onclick="alert( event.target)"> Test</p>[/color]

                              [snip]
                              [color=blue]
                              > Click and get it. I did not create this EVENT object [...][/color]

                              No, the user agent did. When the attribute is encountered, it is converted
                              into an anonymous function internally. Using the Netscape event model, this
                              is exactly equivalent to:

                              pElement.onclic k = function(event) {
                              alert(event.tar get)
                              };

                              You can see this representation (excluding the assignment itself) by showing
                              the toString value, as I stated above.

                              <p onclick="alert( this.onclick);" >Test</p>

                              will display:

                              function(event) {
                              alert(this.oncl ick);
                              }

                              Why is this so difficult to comprehend?
                              [color=blue]
                              > Thus it's a global public self-updating event object.[/color]

                              That's a leap which you cannot support. If true, one could write:

                              function myListener() {
                              alert(event.tar get);
                              }

                              <p onclick="myList ener();">Test</p>

                              and still examine the event object, but you can't outside the IE event
                              model. The identifier is a formal argument of a function object created by
                              the user agent. It is not a global.

                              [snipped nonsense]

                              Mike

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

                              Comment

                              Working...