10 Replies - 913 Views - Last Post: 24 April 2011 - 06:53 PM

#1 cRaZi_RiCaN  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 44
  • Joined: 25-May 07

Applying CSS classes unobtrusively.

Posted 24 April 2011 - 09:12 AM

Greetings,

I am trying to add a class to some <li> elements when they are moused over on. What am I doing wrong?

HTML:

<div id="navigation">
	<ol id = "navigation-buttons" >
		<li><a href = "KmiZa!.html">Home</a></li>
		<li><a href = "about.html">About</a></li>
		<li><a href = "order.html">Order!</a></li>
		<li><a href = "gallery.html">Gallery</a></li>
		<li><a href = "contact.html">Contact</a></li>
		<li><a href = "twitter">Twitter</a></li>
		<li><a href = "facebook">Facebook</a></li>
	</ol>
</div>



CSS:

#navigation ol li
{
	border: 1px solid black;
	margin-bottom: 15px;
	text-align: center;
	padding-left: 5px;
	padding-right: 5px;
	padding-top: 2px;
	padding-bottom: 2px;
}

.isHoverOn
{
	/*To be applied via JS when mouse hovers over buttons*/
	background-color: black;
	border-color: white;
	border-style: double;
        color: white;
}



JS:

function HoverOn()
{
	var navigationButtons = document.getElementsById('navigation-buttons').getElementsByTagName('li');

	for (var i = 0; i < navigationButtons.length; i++)
	{
		if (navigationButtons[i].onmouseover)
		{
			navigationButtons[i].className += " isHoverOn";
		}
	}
}



Is This A Good Question/Topic? 0
  • +

Replies To: Applying CSS classes unobtrusively.

#2 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4337
  • View blog
  • Posts: 12,137
  • Joined: 18-April 07

Re: Applying CSS classes unobtrusively.

Posted 24 April 2011 - 09:26 AM

onmouseover is an event. You have to actually attach the CSS to the item on triggering of the event. In your code above you are simply looping through the navigationButtons and checking if it has an onmouseover and then trying to apply the class. But this code isn't executed when you actually trigger the event.

What you want to be looking at doing is when you first fire up the page, looping through the <li> tags like you are doing, but attaching a function to each of the tags using addEventListener, attachEvent, or setting the function directly to the elements onmouseover property.

Which event attachment mechanism you use depends on the browser of course. IE has their own way of doing things.

Here is an example for firefox using the addEventListener...

function attach() {
	var el = document.getElementById("myElement");
	
	if (el.addEventListener) {
		el.addEventListener ("mouseover",myFunction,false);
	}
}

function myFunction() {
	var el = document.getElementById("myElement");
	
	el.className = "onHoverClass";
}



We would then call attach() in the onload event of the body tag. What it then would do is look up the element with the id "myElement" and see if it supports the addEventListener mechanism. If it does, we attach our "myFunction" function to the element's mouseover event.

Now any time we hover over the element, it will trigger the event which calls our myFunction function and applies the onHoverClass style.

You can attach a separate event to the mouseout event the same way.

Hope you get the idea. :)
Was This Post Helpful? 0
  • +
  • -

#3 cRaZi_RiCaN  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 44
  • Joined: 25-May 07

Re: Applying CSS classes unobtrusively.

Posted 24 April 2011 - 10:38 AM

Hmm, interesting. So how would I be calling the attach() function?
Was This Post Helpful? 0
  • +
  • -

#4 Dormilich  Icon User is online

  • 痛覚残留
  • member icon

Reputation: 3541
  • View blog
  • Posts: 10,239
  • Joined: 08-June 10

Re: Applying CSS classes unobtrusively.

Posted 24 April 2011 - 11:36 AM

what you need to do is invoke the attach() function on every <li> element you want to have the class name changed.

modified example from Martyr2:
// by passing the element itself to the function
// it will get more generic
function attach(el) 
{
	if (el.addEventListener) {
		el.addEventListener ("mouseover", myFunction, false);
	}
}

function myFunction() 
{
	this.className = "onHoverClass";
}



an application example for firefox; you pass every <li> element to attach(), for which we can "misuse" one of the newer Array methods.
// get all <li> elements, may need to be modified 
// according to your needs
var li = document.getElementsByTagName("li");

// apply attach() to every element from above
Array.prototype.forEach.call(li, attach);

// should also work
[].forEach.call(li, attach);

This post has been edited by Dormilich: 24 April 2011 - 11:39 AM

Was This Post Helpful? 0
  • +
  • -

#5 cRaZi_RiCaN  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 44
  • Joined: 25-May 07

Re: Applying CSS classes unobtrusively.

Posted 24 April 2011 - 11:53 AM

Thanks. I now understand the concept of attaching listeners to elements and functions to those listeners, but what I am still not grasping is something much more simpler: Where and how do I write the Javascript code that starts attaching the listeners? How is that code called from a separate JS file when I need it?

So far the examples I see either:
1. Show the JS code with the attach(), but I have no idea how to execute that code from an external JS file.
2. Show the JS code for attaching a listener as in-line or embedded script, but I want to use an external JS file.

If someone could provide a short example with separate HTML and JS code, it would be perfect.
Was This Post Helpful? 0
  • +
  • -

#6 Dormilich  Icon User is online

  • 痛覚残留
  • member icon

Reputation: 3541
  • View blog
  • Posts: 10,239
  • Joined: 08-June 10

Re: Applying CSS classes unobtrusively.

Posted 24 April 2011 - 01:05 PM

the previous code examples work from external files. you only have to make sure, the document is already loaded. on the other hand side, none of the above code works as inline JS.

there is no cardinal difference between an external script and an embedded script.

This post has been edited by Dormilich: 24 April 2011 - 01:09 PM

Was This Post Helpful? 0
  • +
  • -

#7 cRaZi_RiCaN  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 44
  • Joined: 25-May 07

Re: Applying CSS classes unobtrusively.

Posted 24 April 2011 - 02:04 PM

Oh. So who or how is the attach() function, as written above, called? Are these functions called once the JS file is loaded?

This post has been edited by cRaZi_RiCaN: 24 April 2011 - 02:07 PM

Was This Post Helpful? 0
  • +
  • -

#8 Dormilich  Icon User is online

  • 痛覚残留
  • member icon

Reputation: 3541
  • View blog
  • Posts: 10,239
  • Joined: 08-June 10

Re: Applying CSS classes unobtrusively.

Posted 24 April 2011 - 03:06 PM

View PostcRaZi_RiCaN, on 24 April 2011 - 10:04 PM, said:

Oh. So who or how is the attach() function, as written above, called?

second code block, line #6.


View PostcRaZi_RiCaN, on 24 April 2011 - 10:04 PM, said:

Are these functions called once the JS file is loaded?

that depends on where you put it. whether you wrap it in a function or make any other changes to load it in the right place I left up to you (assuming you know how to use external script files correctly).
Was This Post Helpful? 0
  • +
  • -

#9 cRaZi_RiCaN  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 44
  • Joined: 25-May 07

Re: Applying CSS classes unobtrusively.

Posted 24 April 2011 - 03:57 PM

OK, lets give this a second try.

HTML:

<ol id = "navigation-buttons" >
		<li><a href = "KmiZa!.html">Home</a></li>
		<li><a href = "about.html">About</a></li>
		<li><a href = "order.html">Order!</a></li>
		<li><a href = "gallery.html">Gallery</a></li>
		<li><a href = "contact.html">Contact</a></li>
		<li><a href = "twitter">Twitter</a></li>
		<li><a href = "facebook">Facebook</a></li>
</ol>



CSS:

.isHoverOn
{
	/*To be applied via JS when mouse hovers over buttons*/
	background-color: black;
	border: 2px dotted white;

}



JS:

function hasClass(element, classToAdd)
{
	return element.className.match(new RegExp('(\\s|^)' + classToAdd + '(\\s|^)'));
}

function addClass(element, classToAdd)
{
	if (!hasClass(element,classToAdd))
	{
		element.className += " " + classToAdd;
	}
}

function addEventSimple(element, eventType, functionName)
{
	if (element.addEventListener) 
	{
		element.addEventListener(eventType, functionName, false);
	} 
	else if (element.attachEvent) 
	{
		element.attachEvent('on' + eventType, functionName);
	}
}


function HoverOn()
{
	this.addClass(this.nodeName.toLowerCase(),'isHoverOn');
}

var navigationButtons = document.getElementById('navigation-buttons').childNodes;
for (var i = 0; i < navigationButtons.length; i++)
{
	navigationButtons[i].addEventSimple(navigationButtons[i], 'onmouseover', HoverOn);
}



What is wrong now?
Where should I put my link to the JS file? (I am currently putting it before the end body tag)
Was This Post Helpful? 0
  • +
  • -

#10 Dormilich  Icon User is online

  • 痛覚残留
  • member icon

Reputation: 3541
  • View blog
  • Posts: 10,239
  • Joined: 08-June 10

Re: Applying CSS classes unobtrusively.

Posted 24 April 2011 - 04:29 PM

View PostcRaZi_RiCaN, on 24 April 2011 - 11:57 PM, said:

What is wrong now?

look at the error console, it will be listed there.

hint: lines 29 & 35

but to be honest, why using JS what you can do with CSS (hint: :hover)

This post has been edited by Dormilich: 24 April 2011 - 04:33 PM

Was This Post Helpful? 0
  • +
  • -

#11 cRaZi_RiCaN  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 44
  • Joined: 25-May 07

Re: Applying CSS classes unobtrusively.

Posted 24 April 2011 - 06:53 PM

I know it can be done with CSS, but I want to learn JS.

Anyway, I got it working I had a few more errors after the two you pointed out. I did not know browsers came with an error console...hahaha.

Thanks a lot!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1