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);
}