addEventListener code

Hello All,

When the user clicks on a li, this will be highlighted.

<ul class=“outer”>
<li id=“wikipedia”>This is info for Chino in Reno</li>
<li>
<ul class=“inner”>
<li>This is info for Chino in Reno</li>
</ul>
</li>
<li>
<ul class=“inner”>
<li>This is info for Chino in Reno</li>
</ul>
</li>
<li>This is info for Chino in Reno</li>
</ul>

This javascript code works, but I don’t want to use global vars outside of the function object.

    var link = document.getElementById("wikipedia");
    var WikipediaLink =
        {
            init: function()
            {
            link.addEventListener("click", WikipediaLink.clickListener, false);
            },
            clickListener: function()
            {  
            link.setAttribute("class","style");
            }
        };
        WikipediaLink.init();

Instead of copying the var link = document.getElementById(“wikipedia”); like this:

 var WikipediaLink =
        {
            init: function()
            {
        [COLOR="red"]var link = document.getElementById("wikipedia");[/COLOR]
            link.addEventListener("click", WikipediaLink.clickListener, false);
            },
        [COLOR="red"]var link = document.getElementById("wikipedia");[/COLOR]
            clickListener: function(event)
            {
            event.className("style");
            }
        };
        WikipediaLink.init();

How to make it fall through to the clickListener property? The event object isn’t the way, right???

var WikipediaLink =
{
init: function()
{
var link = document.getElementById(“wikipedia”);
link.addEventListener(“click”, WikipediaLink.clickListener, false);
},
clickListener: function(event)
{
event.className(“style”);
}
};
WikipediaLink.init();

With this code you can add any event and class to your element(s):

function addClass(evt, el, cls) {
	return el.addEventListener(
		evt, 
		function(){
			this.setAttribute('class', cls);	
		}, 
		false
	);		
}

// Single Element
addClass('click', document.getElementById('wikipedia'), 'style');

// Multiple Elements
elms = document.querySelectorAll('.outer li');
for(var i = 0; i < elms.length; i++) {
	addClass('mouseover', elms[i], 'style');
}

Sounds like you are potentially repeating this code in a few places?

If you want to abstract this out, you could make an instantiable function that you can simply pass in an ID to, like so:

Lets say we have the following markup:

<ul id="linkList">
	<li id="someItem"><a href="#">skfjnfv</a></li>
	<li><a href="#">sdkvjndfv</a></li>
	<li id="anotherItem"><a href="#">sdkvjnsdfv</a></li>
	<li><a href="#">dkjvnfv</a></li>
	<li id="yetAnotherItem"><a href="#">skjvnsfv</a></li>
</ul>

You could create event handlers inside of an instantiable function like this:

function Linker(id) {
	var that = this; // to deal with scope issues
	
	this.link = document.getElementById(id);
		
	this.init = function() {
		this.link.addEventListener("click", this.clickListener, false);
	};
		
	this.clickListener = function() {
		that.link.setAttribute("class","something");
	}
		
	//execute initialisation
	this.init();
	return this;
}

l1 = new Linker("someItem");
l2 = new Linker("yetAnotherItem");

//uncomment this line to see the objects that are returned.
//console.log(l1, l2);

You could quite easily change this to work on an entire list without requiring IDs on each element:

function Linker(el) { //note that we're accepting an Element now, not an ID
	var that = this; // to deal with scope issues
	
	this.link = el; //we don't need getElementById as we have an element already
	
	this.init = function() {
		this.link.addEventListener("click", this.clickListener, false);
	};
	
	this.clickListener = function() {
		that.link.setAttribute("class","something");
	}
	
	//execute initialisation
	this.init();
	return this;
}


//get all the LIs in the UL
listItems = document.getElementById("linkList").getElementsByTagName("li");

for (var li in listItems) {
	item = listItems[li];
	
	//check that we have correct node type (i.e. an element and not a textnode)
	if (item.nodeType !== 1) { 
		continue;
	}
	
	new Linker(item);
}