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


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

One Event Listner for Multi-Elements- How?

Started bydarin.hensley@gmail.com
First post2012-08-13 21:09 -0700
Last post2012-08-19 00:41 +0100
Articles 10 — 9 participants

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


Contents

  One Event Listner for Multi-Elements- How? darin.hensley@gmail.com - 2012-08-13 21:09 -0700
    Re: One Event Listner for Multi-Elements- How? Stefan Weiss <krewecherl@gmail.com> - 2012-08-14 16:19 +0200
      Re: One Event Listner for Multi-Elements- How? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-08-15 13:40 +0200
        Re: One Event Listner for Multi-Elements- How? MC <news@aisus.com> - 2012-08-15 09:19 -0500
        Re: One Event Listner for Multi-Elements- How? David Mark <dmark.cinsoft@gmail.com> - 2012-08-16 15:42 -0700
      Re: One Event Listner for Multi-Elements- How? dman777 <darin.hensley@gmail.com> - 2012-08-17 16:03 -0700
        Re: One Event Listner for Multi-Elements- How? "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2012-08-18 07:54 +0000
        Re: One Event Listner for Multi-Elements- How? Mike Winter <usenet@michael-winter.me.invalid> - 2012-08-18 19:50 +0100
          Re: One Event Listner for Multi-Elements- How? Gregor Kofler <usenet@gregorkofler.com> - 2012-08-19 01:35 +0200
            Re: One Event Listner for Multi-Elements- How? Mike Winter <usenet@michael-winter.me.invalid> - 2012-08-19 00:41 +0100

#15355 — One Event Listner for Multi-Elements- How?

Fromdarin.hensley@gmail.com
Date2012-08-13 21:09 -0700
SubjectOne Event Listner for Multi-Elements- How?
Message-ID<9e8f3159-7de3-4cac-8775-8935d9badc9e@googlegroups.com>
I have 4 seperate '<div class="links"><a href="#div" id="b1">home</a></div>' elements.

 Each one has a addEventListner("click", home, false)....one for home, photos, media, and bio.

 I read where I can have one addEventlistener for all of them and if the click is detected just distinguish between each one and then perform that action based on the distinction. How would I do this? 

[toc] | [next] | [standalone]


#15358

FromStefan Weiss <krewecherl@gmail.com>
Date2012-08-14 16:19 +0200
Message-ID<k0dmpk$i6k$1@news.albasani.net>
In reply to#15355
On 2012-08-14 06:09, darin.hensley@gmail.com wrote:
> I have 4 seperate '<div class="links"><a href="#div"
> id="b1">home</a></div>' elements.
> 
> Each one has a addEventListner("click", home, false)....one for
> home, photos, media, and bio.
>
> I read where I can have one addEventlistener for all of them and if
> the click is detected just distinguish between each one and then perform
> that action based on the distinction. How would I do this?

This is called "event delegation". The basic idea is that you attach one
listener to an element which contains your links, and decide what to do
in the (single) callback function.

You mentioned addEventListener(). This method is not supported in IE
versions before 9, and there are many other situations in JS DOM event
handling where browser specific behaviors need to be addressed. For the
sake of simplicity, I have omitted them in the code below, so this will
only work in browsers which support the W3C event model (= basically
every current browser apart from IE 8-).

Here's something to get you started:

<div id="container">
    <div class="links"><a href="a.html" id="b1">First link</a></div>
    <div class="links"><a href="b.html" id="b2">Second link</a></div>
    <div class="links"><a href="c.html" id="b3">Third link</a></div>
    <div class="links"><a href="d.html" id="b4">Fourth link</a></div>
</div>

<script>

var container = document.getElementById("container");
container.addEventListener("click", clickHandler, false);

// the single event handler function
function clickHandler (evt) {
    var evtTarget = getEvtTarget(evt);
    if (evtTarget && evtTarget.nodeName.toLowerCase() == "a") {
        evt.preventDefault();  // (IE uses evt.returnValue)
        alert(evtTarget.firstChild.data + " clicked"
            + "; id = " + evtTarget.id
            + "; href = " + evtTarget.href);
    }
}

// makes sure our target is an element node, not just text
function getEvtTarget (evt) {
    var node = evt.target;   // (IE uses evt.srcElement)
    if (node && node.nodeType == 3) {  // 3 = text node
        node = node.parentNode;
    }
    return node;
}

</script>

- stefan

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


#15364

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2012-08-15 13:40 +0200
Message-ID<1971021.WO8UjatxCD@PointedEars.de>
In reply to#15358
Stefan Weiss wrote:

> You mentioned addEventListener(). This method is not supported in IE
> versions before 9, and there are many other situations in JS DOM event
> handling where browser specific behaviors need to be addressed. For the
> sake of simplicity, I have omitted them in the code below, so this will
> only work in browsers which support the W3C event model (= basically
> every current browser apart from IE 8-).

Internet Explorer 9.x and other browsers using mshtml.dll 9.x do not  
support the addEventListener() method and other features of W3C DOM
Level 3 Events when the layout engine is in Quirks Mode.


PointedEars
-- 
> If you get a bunch of authors […] that state the same "best practices"
> in any programming language, then you can bet who is wrong or right...
Not with javascript. Nonsense propagates like wildfire in this field.
  -- Richard Cornford, comp.lang.javascript, 2011-11-14

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


#15366

FromMC <news@aisus.com>
Date2012-08-15 09:19 -0500
Message-ID<d5cde$502bb005$cf9b4e41$20084@ALLTEL.NET>
In reply to#15364
On 8/15/2012 6:40 AM, Thomas 'PointedEars' Lahn wrote:
> Stefan Weiss wrote:
>
>> You mentioned addEventListener(). This method is not supported in IE
>> versions before 9, and there are many other situations in JS DOM event
>> handling where browser specific behaviors need to be addressed. For the
>> sake of simplicity, I have omitted them in the code below, so this will
>> only work in browsers which support the W3C event model (= basically
>> every current browser apart from IE 8-).
>
> Internet Explorer 9.x and other browsers using mshtml.dll 9.x do not
> support the addEventListener() method and other features of W3C DOM
> Level 3 Events when the layout engine is in Quirks Mode.
>
>
> PointedEars

Well, you could run the Chrome plugin and get it in IE.

MC

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


#15380

FromDavid Mark <dmark.cinsoft@gmail.com>
Date2012-08-16 15:42 -0700
Message-ID<acf2d7f2-f02c-4f5a-a12c-8974def4bf34@p14g2000yqk.googlegroups.com>
In reply to#15364
On Aug 15, 7:40 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
> Stefan Weiss wrote:
> > You mentioned addEventListener(). This method is not supported in IE
> > versions before 9, and there are many other situations in JS DOM event
> > handling where browser specific behaviors need to be addressed. For the
> > sake of simplicity, I have omitted them in the code below, so this will
> > only work in browsers which support the W3C event model (= basically
> > every current browser apart from IE 8-).
>
> Internet Explorer 9.x and other browsers using mshtml.dll 9.x do not
> support the addEventListener() method and other features of W3C DOM
> Level 3 Events when the layout engine is in Quirks Mode.

Or when the user or developer forces one of the compatibility modes.
The latter happens when browser sniffing frameworks like Dojo or Ext
JS are used as the next version of IE always breaks them and their
"solution" is to tell developers to force compatibility mode (while
they get to work observing the new version and cobbling together new
sniffs). As for the former, all it takes is a mistaken click of a tiny
and prominently featured button, which shows little indication of its
state.

Some admins force compatibility mode for Intranet sites as well
(usually due to legacy apps that would otherwise break).

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


#15392

Fromdman777 <darin.hensley@gmail.com>
Date2012-08-17 16:03 -0700
Message-ID<54727f88-7419-4a75-817a-519bf5fdc191@googlegroups.com>
In reply to#15358
On Tuesday, August 14, 2012 9:19:32 AM UTC-5, Stefan Weiss wrote:
> On 2012-08-14 06:09, darin  wrote:
> 
> > I have 4 seperate '<div class="links"><a href="#div"
> 
> > id="b1">home</a></div>' elements.
> 
> > 
> 
> > Each one has a addEventListner("click", home, false)....one for
> 
> > home, photos, media, and bio.
> 
> >
> 
> > I read where I can have one addEventlistener for all of them and if
> 
> > the click is detected just distinguish between each one and then perform
> 
> > that action based on the distinction. How would I do this?
> 
> 
> 
> This is called "event delegation". The basic idea is that you attach one
> 
> listener to an element which contains your links, and decide what to do
> 
> in the (single) callback function.
> 
> 
> 
> You mentioned addEventListener(). This method is not supported in IE
> 
> versions before 9, and there are many other situations in JS DOM event
> 
> handling where browser specific behaviors need to be addressed. For the
> 
> sake of simplicity, I have omitted them in the code below, so this will
> 
> only work in browsers which support the W3C event model (= basically
> 
> every current browser apart from IE 8-).
> 
> 
> 
> Here's something to get you started:
> 
> 
> 
> <div id="container">
> 
>     <div class="links"><a href="a.html" id="b1">First link</a></div>
> 
>     <div class="links"><a href="b.html" id="b2">Second link</a></div>
> 
>     <div class="links"><a href="c.html" id="b3">Third link</a></div>
> 
>     <div class="links"><a href="d.html" id="b4">Fourth link</a></div>
> 
> </div>
> 
> 
> 
> <script>
> 
> 
> 
> var container = document.getElementById("container");
> 
> container.addEventListener("click", clickHandler, false);
> 
> 
> 
> // the single event handler function
> 
> function clickHandler (evt) {
> 
>     var evtTarget = getEvtTarget(evt);
> 
>     if (evtTarget && evtTarget.nodeName.toLowerCase() == "a") {
> 
>         evt.preventDefault();  // (IE uses evt.returnValue)
> 
>         alert(evtTarget.firstChild.data + " clicked"
> 
>             + "; id = " + evtTarget.id
> 
>             + "; href = " + evtTarget.href);
> 
>     }
> 
> }
> 
> 
> 
> // makes sure our target is an element node, not just text
> 
> function getEvtTarget (evt) {
> 
>     var node = evt.target;   // (IE uses evt.srcElement)
> 
>     if (node && node.nodeType == 3) {  // 3 = text node
> 
>         node = node.parentNode;
> 
>     }
> 
>     return node;
> 
> }
> 
> 
> 
> </script>
> 
> 
> 
> - stefan

Thanks, I got it to work with:

function buttons(event) {
		if (event.target.id == "b1") home();
		if (event.target.id == "b2") photoBio(true);
		if (event.target.id == "b3") photoBio(false);
		if (event.target == "b4") home();
}

function resetButtons() {
	document.getElementById("buttons").addEventListener( "click", buttons, false);
}


I am still learning and I have a question about this, please...addEventListener passes a object that contains onlcick properties(such as target). In the function buttons(event)...how is it the arguement "event" was able to receive the object from addEventListener when the actual function call is "buttons" and it didn't pass any parameters?

On Tuesday, August 14, 2012 9:19:32 AM UTC-5, Stefan Weiss wrote:
> On 2012-08-14 06:09, darin.hensley@gmail.com wrote:
> 
> > I have 4 seperate '<div class="links"><a href="#div"
> 
> > id="b1">home</a></div>' elements.
> 
> > 
> 
> > Each one has a addEventListner("click", home, false)....one for
> 
> > home, photos, media, and bio.
> 
> >
> 
> > I read where I can have one addEventlistener for all of them and if
> 
> > the click is detected just distinguish between each one and then perform
> 
> > that action based on the distinction. How would I do this?
> 
> 
> 
> This is called "event delegation". The basic idea is that you attach one
> 
> listener to an element which contains your links, and decide what to do
> 
> in the (single) callback function.
> 
> 
> 
> You mentioned addEventListener(). This method is not supported in IE
> 
> versions before 9, and there are many other situations in JS DOM event
> 
> handling where browser specific behaviors need to be addressed. For the
> 
> sake of simplicity, I have omitted them in the code below, so this will
> 
> only work in browsers which support the W3C event model (= basically
> 
> every current browser apart from IE 8-).
> 
> 
> 
> Here's something to get you started:
> 
> 
> 
> <div id="container">
> 
>     <div class="links"><a href="a.html" id="b1">First link</a></div>
> 
>     <div class="links"><a href="b.html" id="b2">Second link</a></div>
> 
>     <div class="links"><a href="c.html" id="b3">Third link</a></div>
> 
>     <div class="links"><a href="d.html" id="b4">Fourth link</a></div>
> 
> </div>
> 
> 
> 
> <script>
> 
> 
> 
> var container = document.getElementById("container");
> 
> container.addEventListener("click", clickHandler, false);
> 
> 
> 
> // the single event handler function
> 
> function clickHandler (evt) {
> 
>     var evtTarget = getEvtTarget(evt);
> 
>     if (evtTarget && evtTarget.nodeName.toLowerCase() == "a") {
> 
>         evt.preventDefault();  // (IE uses evt.returnValue)
> 
>         alert(evtTarget.firstChild.data + " clicked"
> 
>             + "; id = " + evtTarget.id
> 
>             + "; href = " + evtTarget.href);
> 
>     }
> 
> }
> 
> 
> 
> // makes sure our target is an element node, not just text
> 
> function getEvtTarget (evt) {
> 
>     var node = evt.target;   // (IE uses evt.srcElement)
> 
>     if (node && node.nodeType == 3) {  // 3 = text node
> 
>         node = node.parentNode;
> 
>     }
> 
>     return node;
> 
> }
> 
> 
> 
> </script>
> 
> 
> 
> - stefan



On Tuesday, August 14, 2012 9:19:32 AM UTC-5, Stefan Weiss wrote:
> On 2012-08-14 06:09, darin.hensley@gmail.com wrote:
> 
> > I have 4 seperate '<div class="links"><a href="#div"
> 
> > id="b1">home</a></div>' elements.
> 
> > 
> 
> > Each one has a addEventListner("click", home, false)....one for
> 
> > home, photos, media, and bio.
> 
> >
> 
> > I read where I can have one addEventlistener for all of them and if
> 
> > the click is detected just distinguish between each one and then perform
> 
> > that action based on the distinction. How would I do this?
> 
> 
> 
> This is called "event delegation". The basic idea is that you attach one
> 
> listener to an element which contains your links, and decide what to do
> 
> in the (single) callback function.
> 
> 
> 
> You mentioned addEventListener(). This method is not supported in IE
> 
> versions before 9, and there are many other situations in JS DOM event
> 
> handling where browser specific behaviors need to be addressed. For the
> 
> sake of simplicity, I have omitted them in the code below, so this will
> 
> only work in browsers which support the W3C event model (= basically
> 
> every current browser apart from IE 8-).
> 
> 
> 
> Here's something to get you started:
> 
> 
> 
> <div id="container">
> 
>     <div class="links"><a href="a.html" id="b1">First link</a></div>
> 
>     <div class="links"><a href="b.html" id="b2">Second link</a></div>
> 
>     <div class="links"><a href="c.html" id="b3">Third link</a></div>
> 
>     <div class="links"><a href="d.html" id="b4">Fourth link</a></div>
> 
> </div>
> 
> 
> 
> <script>
> 
> 
> 
> var container = document.getElementById("container");
> 
> container.addEventListener("click", clickHandler, false);
> 
> 
> 
> // the single event handler function
> 
> function clickHandler (evt) {
> 
>     var evtTarget = getEvtTarget(evt);
> 
>     if (evtTarget && evtTarget.nodeName.toLowerCase() == "a") {
> 
>         evt.preventDefault();  // (IE uses evt.returnValue)
> 
>         alert(evtTarget.firstChild.data + " clicked"
> 
>             + "; id = " + evtTarget.id
> 
>             + "; href = " + evtTarget.href);
> 
>     }
> 
> }
> 
> 
> 
> // makes sure our target is an element node, not just text
> 
> function getEvtTarget (evt) {
> 
>     var node = evt.target;   // (IE uses evt.srcElement)
> 
>     if (node && node.nodeType == 3) {  // 3 = text node
> 
>         node = node.parentNode;
> 
>     }
> 
>     return node;
> 
> }
> 
> 
> 
> </script>
> 
> 
> 
> - stefan

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


#15409

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2012-08-18 07:54 +0000
Message-ID<XnsA0B364B65DA12eejj99@194.109.133.133>
In reply to#15392
dman777 wrote on 18 aug 2012 in comp.lang.javascript:

> function buttons(event) {
>           if (event.target.id == "b1") home();
>           if (event.target.id == "b2") photoBio(true);
>           if (event.target.id == "b3") photoBio(false);
>           if (event.target == "b4") home();
>}
> 
> function resetButtons() {
>      document.getElementById("buttons").addEventListener( "click",
>      buttons, false); 
>}

Nice, this has lots of possibilities in in compliant browsers,
[but not in pre IE9 or IE-quirksmode].

Some experimenting:

==========================================
<div id=myButtons>
  <button>b1</button><br>
  <button id=b2>b2</button><br>
  <button class=b3>b3a</button><br>
  <button class=b3>b3b</button><br>
  <button>Europe</button><br>
  <button>Africa and America</button><br>
</div>
<hr>
<div id=myOtherButtons title='Year: '>
  <button>1823</button><br>
  <button>2012</button><br>
</div>


<script type='text/javascript'>
function buttons(event) {
  if (event.target.innerHTML == 'b1') alert('===> b1');
  else if (event.target.id == 'b2') alert('===> b2');
  else if (event.target.className == 'b3') alert('===>> b3a or b3b');
  else alert(event.target.parentNode.title + event.target.innerHTML);
};

function setButtonsListener(id) {
  document.getElementById(id).addEventListener( 'click', buttons, false);
};

setButtonsListener('myButtons');
setButtonsListener('myOtherButtons');

</script>
========================================== 


-- 
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

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


#15437

FromMike Winter <usenet@michael-winter.me.invalid>
Date2012-08-18 19:50 +0100
Message-ID<QtRXr.1160237$hg.627221@fx21.am4>
In reply to#15392
On 18/08/2012 00:03, dman777 wrote:

[snip]

> function buttons(event) {
>     if (event.target.id == "b1") home();
>     if (event.target.id == "b2") photoBio(true);
>     if (event.target.id == "b3") photoBio(false);
>     if (event.target == "b4") home();
> }

As these are in reality exclusive tests, it's better form to use 
"if...else": once one of these conditions succeeds, there's no need to 
test the rest. That said, as you're comparing the same value for 
equality each time, you could also use a "select" statement.

> function resetButtons() {
> 	document.getElementById("buttons").addEventListener( "click", buttons, false);
> }
>
>
> I am still learning and I have a question about this, please...addEventListener passes a object that contains onlcick properties(such as target). In the function buttons(event)...how is it the arguement "event" was able to receive the object from addEventListener when the actual function call is "buttons" and it didn't pass any parameters?

You didn't call the "buttons" function above (there are no parentheses), 
you passed a reference to it. Functions here are objects, and just like 
any other object you can make other references to it and use the object 
through those references. Consider:

   function myFunction(text) {
     alert(text);
   }

   var myRef = myFunction;

At this point, both "myFunction" and "myRef" refer to the same function 
object that, when called, will display an alert dialogue box.

   myRef('This is a test!');  // same as calling myFunction(...)

The same principle applies to addEventListener: you give it a reference 
to a function object that it will add to a list of other listener 
functions. When the right event type is triggered, the event handling 
code iterates over this list, calling each function in turn and passing 
the event object as it does so[1].

I hope that helps,
Mike


[1] Imagine, if you will, that HTML element objects have properties like 
these:

   {
     listeners: {
       click: [],
       // ...
     },
     addEventListener: function (eventType, listener, canBubble) {
       if (this.listeners[eventType].indexOf(listener) == -1)
         this.listeners[eventType].push(listener);
       // ...
     },
     dispatchEvent: function (event) {
       for (var i = 0; i < this.listeners[event.type].length; ++i) {
         var retVal = this.listeners[event.type][i].call(this, event);
         // ...
     }
   }


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

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


#15444

FromGregor Kofler <usenet@gregorkofler.com>
Date2012-08-19 01:35 +0200
Message-ID<k0p8ro$t39$1@dont-email.me>
In reply to#15437
Am 2012-08-18 20:50, Mike Winter meinte:
> On 18/08/2012 00:03, dman777 wrote:
>
> [snip]
>
>> function buttons(event) {
>>     if (event.target.id == "b1") home();
>>     if (event.target.id == "b2") photoBio(true);
>>     if (event.target.id == "b3") photoBio(false);
>>     if (event.target == "b4") home();
>> }
>
> As these are in reality exclusive tests, it's better form to use
> "if...else": once one of these conditions succeeds, there's no need to
> test the rest. That said, as you're comparing the same value for
> equality each time, you could also use a "select" statement.

You meant "switch"?

Gregor

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


#15445

FromMike Winter <usenet@michael-winter.me.invalid>
Date2012-08-19 00:41 +0100
Message-ID<OKVXr.1581148$%k.1167513@fx20.am4>
In reply to#15444
On 19/08/2012 00:35, Gregor Kofler wrote:
> Am 2012-08-18 20:50, Mike Winter meinte:
>> [...]  you could also use a "select" statement.
>
> You meant "switch"?

Beg your pardon. I did, of course.

Thanks,
-- 
Mike Winter
Replace ".invalid" with ".uk" to reply by e-mail.

[toc] | [prev] | [standalone]


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


csiph-web