Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #8629 > unrolled thread

<ul><li><ul><li>... onclick() only for one node ?

Started byJörg Weule <weule@7b5.de>
First post2011-11-25 16:10 +0100
Last post2011-11-26 12:51 +0100
Articles 13 — 6 participants

Back to article view | Back to comp.lang.javascript


Contents

  <ul><li><ul><li>... onclick() only for one node ? Jörg Weule <weule@7b5.de> - 2011-11-25 16:10 +0100
    Re: <ul><li><ul><li>... onclick() only for one node ? Arno Welzel <usenet@arnowelzel.de> - 2011-11-25 17:30 +0100
    Re: <ul><li><ul><li>... onclick() only for one node ? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-25 17:58 +0100
      Re: <ul><li><ul><li>... onclick() only for one node ? Jörg Weule <weule@7b5.de> - 2011-11-25 18:42 +0100
        Re: <ul><li><ul><li>... onclick() only for one node ? Martin Honnen <mahotrash@yahoo.de> - 2011-11-25 19:11 +0100
          Re: <ul><li><ul><li>... onclick() only for one node ? Jörg Weule <weule@7b5.de> - 2011-11-25 19:37 +0100
          Re: <ul><li><ul><li>... onclick() only for one node ? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-25 20:04 +0100
    Re: <ul><li><ul><li>... onclick() only for one node ? "Jukka K. Korpela" <jkorpela@cs.tut.fi> - 2011-11-25 20:27 +0200
      Re: <ul><li><ul><li>... onclick() only for one node ? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-25 20:28 +0100
        Re: <ul><li><ul><li>... onclick() only for one node ? "J.R." <groups_jr-1@yahoo.com.br> - 2011-11-25 21:57 -0200
          Re: <ul><li><ul><li>... onclick() only for one node ? "Jukka K. Korpela" <jkorpela@cs.tut.fi> - 2011-11-26 09:14 +0200
            Re: <ul><li><ul><li>... onclick() only for one node ? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-26 12:53 +0100
          Re: <ul><li><ul><li>... onclick() only for one node ? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2011-11-26 12:51 +0100

#8629 — <ul><li><ul><li>... onclick() only for one node ?

FromJörg Weule <weule@7b5.de>
Date2011-11-25 16:10 +0100
Subject<ul><li><ul><li>... onclick() only for one node ?
Message-ID<9j9pfhFe3lU1@mid.individual.net>
Hello,

at <ul><li><ul><li>...</li></ul></li></ul> I got the click event on the 
whole tree and want to process the event for only on one node.

How can i stop the event processing calling my function for any node at 
the hirachie?

With kind regards

Jörg

[toc] | [next] | [standalone]


#8635

FromArno Welzel <usenet@arnowelzel.de>
Date2011-11-25 17:30 +0100
Message-ID<4ECFC2BB.4080804@arnowelzel.de>
In reply to#8629
Jörg Weule, 2011-11-25 16:10:

> Hello,
> 
> at <ul><li><ul><li>...</li></ul></li></ul> I got the click event on the 
> whole tree and want to process the event for only on one node.
> 
> How can i stop the event processing calling my function for any node at 
> the hirachie?

You have to stop event bubbling in your handler.


-- 
Arno Welzel
http://arnowelzel.de
http://de-rec-fahrrad.de

[toc] | [prev] | [next] | [standalone]


#8636

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2011-11-25 17:58 +0100
Message-ID<1834269.dtTrMRavdF@PointedEars.de>
In reply to#8629
Jörg Weule wrote:

> at <ul><li><ul><li>...</li></ul></li></ul> I got the click event on the
> whole tree and want to process the event for only on one node.
> 
> How can i stop the event processing calling my function for any node at
> the hirachie?

If this is really only for one node, you can call the stopPropagation() 
method (standards-compliant) or set the event object's `cancelBubble' 
property to `true' (MSHTML) in the event listener.  However, the drawback of 
this is that *no* element "upwards" in the tree will receive that event 
then, which may not be wanted.

If the latter is important, or if this instead for multiple nodes at the 
same nesting level, you should not do this.  For then you need to stop event 
progagation at every child node.  This comparably inefficient approach is 
propagated by, e. g., jQuery and other selector-based libraries, where you 
would first select elements by a criterion (usually a `class' attribute 
value) and then add an event listener to each matching element.

It is therefore better (for bubbling events like `click') to add only one 
event listener to an ancestor element (here: the `ul' element) in which you 
compare the event target against the object the event has bubbled up to 
(e.target == this, or e.srcElement == this in MSHTML [do not use 
attachEvent()]), and only perform the action for relevant event targets.  In 
case of remaining ambiguity, you can use e. g. the event target's `class' 
attribute value as well.  Be aware that text nodes can be event targets, 
too.


PointedEars
-- 
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

[toc] | [prev] | [next] | [standalone]


#8638

FromJörg Weule <weule@7b5.de>
Date2011-11-25 18:42 +0100
Message-ID<9ja2cgFlpkU1@mid.individual.net>
In reply to#8636
thanks for that.

Not I can write <div onClick()="doMyFunction(event.target)"> to get the 
inner clicked element but Firefox is not accepting

var l = document.createElement("li");
l.onclick = function(){ doMyFunction(event.target) ; } ;

Here I got "event is not defined".

Jörg

On 11/25/2011 05:58 PM, Thomas 'PointedEars' Lahn wrote:
> Jörg Weule wrote:
>
>> at<ul><li><ul><li>...</li></ul></li></ul>  I got the click event on the
>> whole tree and want to process the event for only on one node.
>>
>> How can i stop the event processing calling my function for any node at
>> the hirachie?
>
> If this is really only for one node, you can call the stopPropagation()
> method (standards-compliant) or set the event object's `cancelBubble'
> property to `true' (MSHTML) in the event listener.  However, the drawback of
> this is that *no* element "upwards" in the tree will receive that event
> then, which may not be wanted.
>
> If the latter is important, or if this instead for multiple nodes at the
> same nesting level, you should not do this.  For then you need to stop event
> progagation at every child node.  This comparably inefficient approach is
> propagated by, e. g., jQuery and other selector-based libraries, where you
> would first select elements by a criterion (usually a `class' attribute
> value) and then add an event listener to each matching element.
>
> It is therefore better (for bubbling events like `click') to add only one
> event listener to an ancestor element (here: the `ul' element) in which you
> compare the event target against the object the event has bubbled up to
> (e.target == this, or e.srcElement == this in MSHTML [do not use
> attachEvent()]), and only perform the action for relevant event targets.  In
> case of remaining ambiguity, you can use e. g. the event target's `class'
> attribute value as well.  Be aware that text nodes can be event targets,
> too.
>
>
> PointedEars

[toc] | [prev] | [next] | [standalone]


#8640

FromMartin Honnen <mahotrash@yahoo.de>
Date2011-11-25 19:11 +0100
Message-ID<4ecfda5e$0$7617$9b4e6d93@newsspool1.arcor-online.net>
In reply to#8638
Jörg Weule wrote:

> Not I can write <div onClick()="doMyFunction(event.target)"> to get the
> inner clicked element but Firefox is not accepting
>
> var l = document.createElement("li");
> l.onclick = function(){ doMyFunction(event.target) ; } ;
>
> Here I got "event is not defined".

The proper approach is
   var l = document.createElement("li");
   l.onclick = function(evt) {
     doMyFunction(evt.target);
   };
at least for Mozilla, Opera, Safari, Chrome and IE 9 (in IE 9 mode).
For earlier IE versions you need
   var l = document.createElement("li");
   l.onclick = function(evt) {
     var event = evt || window.event;
     doMyFunction(event.target || event.srcElement);
   };


-- 

	Martin Honnen --- MVP Data Platform Development
	http://msmvps.com/blogs/martin_honnen/

[toc] | [prev] | [next] | [standalone]


#8642

FromJörg Weule <weule@7b5.de>
Date2011-11-25 19:37 +0100
Message-ID<9ja5k6FgaaU1@mid.individual.net>
In reply to#8640
On 11/25/2011 07:11 PM, Martin Honnen wrote:
> Jörg Weule wrote:
>
>> Not I can write <div onClick()="doMyFunction(event.target)"> to get the
>> inner clicked element but Firefox is not accepting
>>
>> var l = document.createElement("li");
>> l.onclick = function(){ doMyFunction(event.target) ; } ;
>>
>> Here I got "event is not defined".
>
> The proper approach is
> var l = document.createElement("li");
> l.onclick = function(evt) {
> doMyFunction(evt.target);
> };
> at least for Mozilla, Opera, Safari, Chrome and IE 9 (in IE 9 mode).
> For earlier IE versions you need
> var l = document.createElement("li");
> l.onclick = function(evt) {
> var event = evt || window.event;
> doMyFunction(event.target || event.srcElement);
> };
>
>
Of cause: l.onclick = function(evt) {...}
One signal handler at the top ul sounds reasonable and works great.

Thanks a lot.

Jörg

[toc] | [prev] | [next] | [standalone]


#8643

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2011-11-25 20:04 +0100
Message-ID<2567763.1uUHiEQOGO@PointedEars.de>
In reply to#8640
Martin Honnen wrote:

> Jörg Weule wrote:
>> Not I can write <div onClick()="doMyFunction(event.target)"> to get the
>> inner clicked element but Firefox is not accepting
>>
>> var l = document.createElement("li");
>> l.onclick = function(){ doMyFunction(event.target) ; } ;
>>
>> Here I got "event is not defined".
> 
> The proper approach is
>    var l = document.createElement("li");
>    l.onclick = function(evt) {
>      doMyFunction(evt.target);
>    };
> at least for Mozilla, Opera, Safari, Chrome and IE 9 (in IE 9 mode).
> For earlier IE versions you need
>    var l = document.createElement("li");
>    l.onclick = function(evt) {
>      var event = evt || window.event;
>      doMyFunction(event.target || event.srcElement);
>    };

If one uses the more error-prone boolean shortcut syntax instead of `typeof' 
testing, it should be

     l.onclick = function(evt) {
       var event = evt || window.event;
       if (event)
       {
         doMyFunction(event.target || event.srcElement);
       }
     };

as one should not assume that if `evt' type-converts to false, 
`window.event' must refer to an object.  However, that approach is 
proprietary, even though for historical reasons it is probably most 
compatible.

The standards-compliant approach is, and the proper approach has become

     l.addEventListener("click", function(evt) {
       doMyFunction(evt.target);
     }, false);

since IE/MSHTML 9 supports it in Standards Mode.  Until that remains less 
compatible (there is still IE/MSHTML < 9), using a wrapper method like 
jsx.dom.addEventListener() [1] is recommended, so as not to overwritethe 
primary event listener if one has been added, e. g., with the `onclick' 
attribute, and not to interfere with the order of event listeners of an 
element.


PointedEars
___________
[1] 
<http://pointedears.de/websvn/filedetails.php?repname=JSX&path=%2Ftrunk%2Fdom%2Fevents.js>
-- 
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

[toc] | [prev] | [next] | [standalone]


#8641

From"Jukka K. Korpela" <jkorpela@cs.tut.fi>
Date2011-11-25 20:27 +0200
Message-ID<jaommj$c2$1@dont-email.me>
In reply to#8629
2011-11-25 17:10, Jörg Weule wrote:

> at <ul><li><ul><li>...</li></ul></li></ul> I got the click event on the
> whole tree and want to process the event for only on one node.

Applying the techniques explained at
http://www.quirksmode.org/js/events_order.html
you could write

var l = document.createElement("li");
l.onclick = handler;
function handler(e)
{
	if (!e) var e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	// do the real handling here
}

-- 
Yucca, http://www.cs.tut.fi/~jkorpela/

[toc] | [prev] | [next] | [standalone]


#8644

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2011-11-25 20:28 +0100
Message-ID<2194421.p0D5BbiEc1@PointedEars.de>
In reply to#8641
Jukka K. Korpela wrote:

> 2011-11-25 17:10, Jörg Weule wrote:
>> at <ul><li><ul><li>...</li></ul></li></ul> I got the click event on the
>> whole tree and want to process the event for only on one node.
> 
> Applying the techniques explained at
> http://www.quirksmode.org/js/events_order.html
> you could write
> 
> var l = document.createElement("li");
> l.onclick = handler;
> function handler(e)
> {
> if (!e) var e = window.event;

That `VariableDeclaration' is pointless; it also reduces runtime efficiency 
slightly.  The Variable Object (or the Variable Environment) already had the 
variable `e' instantiated per the function's argument list, so the 
VariableDeclaration has no effect (other than checking for a previous 
binding, which is what reduces runtime efficiency).  [ES 5.1, section 10.5]

> e.cancelBubble = true;
> if (e.stopPropagation) e.stopPropagation();
> // do the real handling here
> }

One should *either* attempt to set the `cancelBubble' property to `true' 
*or* attempt to call the stopPropagation() method, depending on what is the 
result of a feature test, because `e' refers to a host object and should not 
be accidentally augmented.  To that end, jsx.dom.createEventListener() 
solves this with

    e2.stopPropagation = (function(e) {
      if (jsx_object.isMethod(e, "stopPropagation"))
      {
        return function() {
          e.stopPropagation();
        };
      }
      
      if (typeof e.cancelBubble != "undefined")
      {
        return function() {
          e.cancelBubble = true;
        };
      }
    })(e);

`e2' is a reference to a native user-defined object that is passed in place 
of the event host object (referred to by `e') to the wrapped event listener 
then (revision 233, line 459):

  return f.call(this, e2);

Which allows to call e.stopPropagation() in the wrapped listener (f) 
regardless which DOM implementation is supported.

A similar wrapper method exists for the preventDefault() method.  But it 
turns out that the `returnValue' property, which is the proprietary 
replacement for the preventDefault() method, cannot be feature-tested.
So `returnValue' is used if preventDefault() is unavailable regardless.

The original event object is available with the `originalEvent' property
of the object referred to by `e2'.

AISB, the proprietary event handler properties should be avoided.


PointedEars
-- 
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
  -- Richard Cornford, cljs, <f806at$ail$1$8300dec7@news.demon.co.uk>

[toc] | [prev] | [next] | [standalone]


#8648

From"J.R." <groups_jr-1@yahoo.com.br>
Date2011-11-25 21:57 -0200
Message-ID<japa23$krr$1@speranza.aioe.org>
In reply to#8644
On 25/11/2011 17:28, Thomas 'PointedEars' Lahn wrote:
> Jukka K. Korpela wrote:
>
>> 2011-11-25 17:10, Jörg Weule wrote:
>>> at<ul><li><ul><li>...</li></ul></li></ul>  I got the click event on the
>>> whole tree and want to process the event for only on one node.
>>
>> Applying the techniques explained at
>> http://www.quirksmode.org/js/events_order.html
>> you could write
>>
>> var l = document.createElement("li");
>> l.onclick = handler;
>> function handler(e)
>> {
>> if (!e) var e = window.event;
>
> That `VariableDeclaration' is pointless; it also reduces runtime efficiency
> slightly.  The Variable Object (or the Variable Environment) already had the
> variable `e' instantiated per the function's argument list, so the
> VariableDeclaration has no effect (other than checking for a previous
> binding, which is what reduces runtime efficiency).  [ES 5.1, section 10.5]
>

ACK as to 'VariableDeclaration is pointless', although that reduction in 
runtime efficiency, if noticeable / measurable, should be dependent on 
the actual JavaScript Engine in use.

>> e.cancelBubble = true;
>> if (e.stopPropagation) e.stopPropagation();
>> // do the real handling here
>> }
>
> One should *either* attempt to set the `cancelBubble' property to `true'
> *or* attempt to call the stopPropagation() method, depending on what is the
> result of a feature test, because `e' refers to a host object and should not
> be accidentally augmented.  To that end, jsx.dom.createEventListener()
> solves this with
>
>      e2.stopPropagation = (function(e) {
>        if (jsx_object.isMethod(e, "stopPropagation"))
>        {
>          return function() {
>            e.stopPropagation();
>          };
>        }
>
>        if (typeof e.cancelBubble != "undefined")
>        {
>          return function() {
>            e.cancelBubble = true;
>          };
>        }
>      })(e);
>

"Either cancelBubble property or stopPropagation() method" means only 
one check is necessary, not both, as there is not a 3rd option. So:

   e2.cancelPropagation = function (e) {
     e = e || window.event;
     if (typeof e.stopPropagation !== 'undefined') { // W3C standard
       e.stopPropagation();
     } else { e.cancelBubble = true; } // IE
   };


> `e2' is a reference to a native user-defined object that is passed in place
> of the event host object (referred to by `e') to the wrapped event listener
> then (revision 233, line 459):
>
>    return f.call(this, e2);
>
> Which allows to call e.stopPropagation() in the wrapped listener (f)
> regardless which DOM implementation is supported.
>
> A similar wrapper method exists for the preventDefault() method.  But it
> turns out that the `returnValue' property, which is the proprietary
> replacement for the preventDefault() method, cannot be feature-tested.
> So `returnValue' is used if preventDefault() is unavailable regardless.
>
   someObj.cancelDefault = function (e) {
     e = e || window.event;
     if (typeof e.preventDefault !== 'undefined') { // W3C standard
       e.preventDefault();
     } else { e.returnValue = false; } // IE
   };

<snip>


-- 
Joao Rodrigues (J.R.)

[toc] | [prev] | [next] | [standalone]


#8649

From"Jukka K. Korpela" <jkorpela@cs.tut.fi>
Date2011-11-26 09:14 +0200
Message-ID<jaq3jm$h66$1@dont-email.me>
In reply to#8648
2011-11-26 1:57, J.R. wrote:

> "Either cancelBubble property or stopPropagation() method" means only
> one check is necessary, not both, as there is not a 3rd option.

And, in reality, as the page I mentioned says, you can assign to 
e.cancelBubble without a check, as adding a property to an object causes 
no real harm.

There are of course people who just have to complain about any code that 
solves a problem, claiming it to be risky, with some vague abstract 
arguments. They don't identify any real harm. And the added code or 
different, longer, more complex code they may suggest of course causes 
much bigger risks than those it is claimed to avoid.

-- 
Yucca, http://www.cs.tut.fi/~jkorpela/

[toc] | [prev] | [next] | [standalone]


#8652

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2011-11-26 12:53 +0100
Message-ID<1951615.nKmheAe9J7@PointedEars.de>
In reply to#8649
Jukka K. Korpela wrote:

> 2011-11-26 1:57, J.R. wrote:
>> "Either cancelBubble property or stopPropagation() method" means only
>> one check is necessary, not both, as there is not a 3rd option.
> 
> And, in reality, as the page I mentioned says, you can assign to
> e.cancelBubble without a check, as adding a property to an object causes
> no real harm.
> 
> There are of course people who just have to complain about any code that
> solves a problem, […]

Your arrogance is the cause of your ignorance, which blinds you for the 
possibilities that await you.


PointedEars
-- 
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

[toc] | [prev] | [next] | [standalone]


#8651

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2011-11-26 12:51 +0100
Message-ID<4794912.ypaU67uLZW@PointedEars.de>
In reply to#8648
J.R. wrote:

> On 25/11/2011 17:28, Thomas 'PointedEars' Lahn wrote:
>> Jukka K. Korpela wrote:
>>> 2011-11-25 17:10, Jörg Weule wrote:
>>>> at<ul><li><ul><li>...</li></ul></li></ul>  I got the click event on the
>>>> whole tree and want to process the event for only on one node.
>>>
>>> Applying the techniques explained at
>>> http://www.quirksmode.org/js/events_order.html
>>> you could write
>>>
>>> var l = document.createElement("li");
>>> l.onclick = handler;
>>> function handler(e)
>>> {
>>> if (!e) var e = window.event;
>>
>> That `VariableDeclaration' is pointless; it also reduces runtime
>> efficiency slightly.  The Variable Object (or the Variable Environment)
>> already had the variable `e' instantiated per the function's argument
>> list, so the VariableDeclaration has no effect (other than checking for a
>> previous binding, which is what reduces runtime efficiency).  [ES 5.1,
>> section 10.5]
> 
> ACK as to 'VariableDeclaration is pointless', although that reduction in
> runtime efficiency, if noticeable / measurable, should be dependent on
> the actual JavaScript Engine in use.

There are only two JavaScript engines (in different languages and versions).  
Whether the difference is noticeable depends not only on the ECMAScript 
implementation.  However, a conforming implementation must implement that 
algorithm one way or the other, so there is without doubt a reduction in 
runtime efficiency.
 
>>> e.cancelBubble = true;
>>> if (e.stopPropagation) e.stopPropagation();
>>> // do the real handling here
>>> }
>>
>> One should *either* attempt to set the `cancelBubble' property to `true'
>> *or* attempt to call the stopPropagation() method, depending on what is
>> the result of a feature test, because `e' refers to a host object and
>> should not be accidentally augmented.  To that end,
>> jsx.dom.createEventListener() solves this with
>>
>>      e2.stopPropagation = (function(e) {
>>        if (jsx_object.isMethod(e, "stopPropagation"))
>>        {
>>          return function() {
>>            e.stopPropagation();
>>          };
>>        }
>>
>>        if (typeof e.cancelBubble != "undefined")
>>        {
>>          return function() {
>>            e.cancelBubble = true;
>>          };
>>        }
>>      })(e);
> 
> "Either cancelBubble property or stopPropagation() method" means only
> one check is necessary, not both, as there is not a 3rd option.

You are mistaken.

> So:
> 
>    e2.cancelPropagation = function (e) {
>      e = e || window.event;

Inefficient and error-prone.

>      if (typeof e.stopPropagation !== 'undefined') { // W3C standard

Error-prone and insufficient.

>        e.stopPropagation();
>      } else { e.cancelBubble = true; } // IE
>    };

That would augment the host object referred to by `e' if it did not have a 
`cancelBubble' property.

>> `e2' is a reference to a native user-defined object that is passed in
>> place of the event host object (referred to by `e') to the wrapped event
>> listener then (revision 233, line 459):
>>
>>    return f.call(this, e2);
>>
>> Which allows to call e.stopPropagation() in the wrapped listener (f)
>> regardless which DOM implementation is supported.
>>
>> A similar wrapper method exists for the preventDefault() method.  But it
>> turns out that the `returnValue' property, which is the proprietary
>> replacement for the preventDefault() method, cannot be feature-tested.
>> So `returnValue' is used if preventDefault() is unavailable regardless.
> 
>    someObj.cancelDefault = function (e) {
>      e = e || window.event;

Inefficient and error-prone.

>      if (typeof e.preventDefault !== 'undefined') { // W3C standard

Error-prone and insufficient.

>        e.preventDefault();
>      } else { e.returnValue = false; } // IE
>    };

You are missing the point, which is that an exception to the rule must be 
made with this property.  Your "IE" also is an oversimplification.  You 
would have known all this had you read my postings in this thread more 
carefully.


PointedEars
-- 
When all you know is jQuery, every problem looks $(olvable).

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web