Go Back   CodingForums.com > :: Client side development > JavaScript programming > Post a JavaScript

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 09-17-2012, 03:09 PM   PM User | #1
AndrewGSW
Senior Coder

 
Join Date: Apr 2011
Location: London, England
Posts: 2,120
Thanks: 15
Thanked 354 Times in 353 Posts
AndrewGSW will become famous soon enough
Event Delegation

This example demonstrates Event Delegation in JavaScript; or, at least, my interpretation of this topic

Event delegation has two related meanings. In languages other than JS a delegate is an object that is created specifically to respond to an event on an object (or objects). The simpler meaning for this example is the following:

Quote:
We attach an event to a parent object and, when the event occurs, we discover which specific child-element was the target of the event.
People commonly loop through rows of a table, or list-items, attaching an event (such as click) to each row/td or item. Depending on how the event is attached, each element may obtain their own copy of the event. This is inefficient and can largely be avoided.

The following example attaches the click event to the (parent) ol-element. When this is clicked we respond to the event BUT ONLY FOR LI-ITEMS. The counter confirms that there is only one instance of the alertText() function.

Code:
<!DOCTYPE html>
<html>
<head>
<title>Some Title</title>
<script type="text/javascript">
var addEvent = function (elem, eventType, func) {
    if ( elem.addEventListener )
        addEvent = function (elem, eventType, func) {
            elem.addEventListener(eventType, func, false);
        };
    else if ( elem.attachEvent )
        addEvent = function (elem, eventType, func) {
            elem.attachEvent('on' + eventType, func);
        };
    else
        addEvent = function (elem, eventType, func) {
            elem['on' + eventType] = func;
        };
    addEvent(elem, eventType, func);
};

var delegateEvent = function (elem, childElems, eventType, func) {
    addEvent(elem, eventType, function (e) {
        var evt = e || window.event;
        var elem = evt.target || evt.srcElement;
        if ( elem.nodeName.toLowerCase() === childElems.toLowerCase() ) {
            func(elem);
        }
    });
}

function alertText(obj) {
    this.counter = this.counter || 1;
    alert(counter++ + ' hits :' + obj.innerHTML);
}

function init() {
    delegateEvent(document.getElementById('thelist'), 'li', 'click', alertText);
}

addEvent(window, 'load', init);
</script>

</head>

<body>
<ul id="thelist">
    <li>The first line</li>
    <li>.. and the second one</li>
    <li>just a third..</li>
    <li>and finally, a fourth.</li>
</ul>


</body>
</html>
__________________
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
Validate your HTML and CSS

Last edited by AndrewGSW; 09-19-2012 at 12:56 AM..
AndrewGSW is offline   Reply With Quote
Old 09-17-2012, 09:33 PM   PM User | #2
AndrewGSW
Senior Coder

 
Join Date: Apr 2011
Location: London, England
Posts: 2,120
Thanks: 15
Thanked 354 Times in 353 Posts
AndrewGSW will become famous soon enough
Below is an expanded version that also passes arguments to the delegated event:

It will highlight rows as you mouseover them using a supplied colour argument, also (optionally) displaying the row number ("Row 1", etc.). When the mouse moves out the previous background colour is re-instated and the temporary title ("Row 1", etc.) is removed.

Code:
<!DOCTYPE html>
<html>
<head>
<title>Highlight Rows</title>
<style type="text/css">
    table {
        background-color: lightgreen;
    }
</style>
<script type="text/javascript">
var addEvent = function (elem, eventType, func) {
    if ( elem.addEventListener )
        addEvent = function (elem, eventType, func) {
            elem.addEventListener(eventType, func, false);
        };
    else if ( elem.attachEvent )
        addEvent = function (elem, eventType, func) {
            elem.attachEvent('on' + eventType, func);
        };
    else
        addEvent = function (elem, eventType, func) {
            elem['on' + eventType] = func;
        };
    addEvent(elem, eventType, func);
};

var delegateEvent = function (elem, childElems, eventType, func, args) {
    addEvent(elem, eventType, function (e) {
        var evt = e || window.event;
        var elem = evt.target || evt.srcElement;
        if ( elem.nodeName.toLowerCase() === childElems.toLowerCase() ) {
            func(elem, args);
        }
    });
};

function highlightRows(obj, args) {
    if (args && args.over && args.over === true) {
        obj.prevColour = obj.parentNode.style.backgroundColor;
        obj.parentNode.style.backgroundColor = args.colour;
        if (args.index && obj.title=="")
            obj.title = "Row " + obj.parentNode.rowIndex;
    } else {
        obj.parentNode.style.backgroundColor = obj.prevColour;
        if (obj.title.indexOf("Row ") + 1)
            obj.title = "";
    }
}

function init() {
    delegateEvent(document.getElementById('thetable'), 'td', 'mouseover',
                  highlightRows, {'colour': 'lightblue', 'over': true, 'index': true});
    delegateEvent(document.getElementById('thetable'), 'td', 'mouseout',
                  highlightRows, {'over': false});
}

addEvent(window, 'load', init);
</script>

</head>

<body>
<table id="thetable" summary="highlight demo">
    <tr><td>Just one</td><td>.. no another</td></tr>
    <tr><td>Second</td><td>.. no another</td></tr>
    <tr style="background-color: yellow;"><td>A third</td><td>.. no another</td></tr>
    <tr><td>Fourth for luck</td><td>.. no another</td></tr>
</table>


</body>
</html>
If the background colours were set using a stylesheet, rather than inline, then it would not be necessary to store the 'prevColour': setting the colour to "" would set the rows back to their original colours.
__________________
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
Validate your HTML and CSS

Last edited by AndrewGSW; 09-18-2012 at 01:51 AM.. Reason: childElems.toLowerCase
AndrewGSW is offline   Reply With Quote
Old 09-19-2012, 01:04 AM   PM User | #3
DaveyErwin
Regular Coder

 
Join Date: Aug 2010
Posts: 806
Thanks: 12
Thanked 168 Times in 166 Posts
DaveyErwin is on a distinguished road
Code:
var addEvent = function (elem, eventType, func) {     if ( elem.addEventListener )         addEvent = function (elem, eventType, func) {             elem.addEventListener(eventType, func, false);         };     else if ( elem.attachEvent )         addEvent = function (elem, eventType, func) {             elem.attachEvent('on' + eventType, func);         };     else         addEvent = function (elem, eventType, func) {             elem['on' + eventType] = func;         };     addEvent(elem, eventType, func); };
do you know of
a browser that will
execute the red code ?
DaveyErwin is offline   Reply With Quote
Old 09-19-2012, 01:35 AM   PM User | #4
AndrewGSW
Senior Coder

 
Join Date: Apr 2011
Location: London, England
Posts: 2,120
Thanks: 15
Thanked 354 Times in 353 Posts
AndrewGSW will become famous soon enough
Quote:
Originally Posted by DaveyErwin View Post
Code:
var addEvent = function (elem, eventType, func) {     if ( elem.addEventListener )         addEvent = function (elem, eventType, func) {             elem.addEventListener(eventType, func, false);         };     else if ( elem.attachEvent )         addEvent = function (elem, eventType, func) {             elem.attachEvent('on' + eventType, func);         };     else         addEvent = function (elem, eventType, func) {             elem['on' + eventType] = func;         };     addEvent(elem, eventType, func); };
do you know of
a browser that will
execute the red code ?
No I don't: it could safely be removed.
__________________
"I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
Validate your HTML and CSS
AndrewGSW is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 10:47 AM.


Advertisement
Log in to turn off these ads.