Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Change link color on div hover

Reply
Thread Tools

Change link color on div hover

 
 
Krys
Guest
Posts: n/a
 
      06-07-2009
Hopefully a simple request:

I have navigation as a css styled ul, all contained within a larger
DIV. I would like to have the color of all the <a> elements change on
mouseover the outside div, but I can't seem to get the syntax right.

Here's what isn't working:

<div id="navigation" onmouseover="document.getElementById('navlist
a').style.color='#000';">
<ul id="navlist">
<li><a href="#">Link1</a></li>
<li><a href="#">Link2</a></li>
<li><a href="#">Link3</a></li>
<li><a href="#">Link4</a></li>
<li><a href="#">Link5</a></li>
<li><a href="#">Link6</a></li>
</ul>
</div>

Any help greatly appreciated!
 
Reply With Quote
 
 
 
 
rf
Guest
Posts: n/a
 
      06-07-2009
Krys wrote:
> Hopefully a simple request:
>
> I have navigation as a css styled ul, all contained within a larger
> DIV. I would like to have the color of all the <a> elements change on
> mouseover the outside div, but I can't seem to get the syntax right.
>
> Here's what isn't working:
>
> <div id="navigation" onmouseover="document.getElementById('navlist
> a').style.color='#000';">
> <ul id="navlist">
> <li><a href="#">Link1</a></li>
> <li><a href="#">Link2</a></li>
> <li><a href="#">Link3</a></li>
> <li><a href="#">Link4</a></li>
> <li><a href="#">Link5</a></li>
> <li><a href="#">Link6</a></li>
> </ul>
> </div>
>
> Any help greatly appreciated!


No javascript required, just a little bit of CSS:

#navigation:hover a {color: #000;}


 
Reply With Quote
 
 
 
 
SAM
Guest
Posts: n/a
 
      06-07-2009
Le 6/7/09 6:55 AM, rf a écrit :
> Krys wrote:
>> Hopefully a simple request:
>>
>> I have navigation as a css styled ul, all contained within a larger
>> DIV. I would like to have the color of all the <a> elements change on
>> mouseover the outside div, but I can't seem to get the syntax right.
>>
>> Here's what isn't working:
>>
>> <div id="navigation" onmouseover="document.getElementById('navlist
>> a').style.color='#000';">
>> <ul id="navlist">
>> <li><a href="#">Link1</a></li>
>> <li><a href="#">Link2</a></li>
>> <li><a href="#">Link3</a></li>
>> <li><a href="#">Link4</a></li>
>> <li><a href="#">Link5</a></li>
>> <li><a href="#">Link6</a></li>
>> </ul>
>> </div>
>>
>> Any help greatly appreciated!

>
> No javascript required, just a little bit of CSS:
>
> #navigation:hover a {color: #000;}


Not with all browsers ...


<div id="navigation"
onmouseover="this.className='over';"
onmouseout="this.className='';">


CSS:
====
#navigation.over #navlist a { color: #000 }


--
sm
 
Reply With Quote
 
Krys
Guest
Posts: n/a
 
      06-07-2009

>
> No javascript required, just a little bit of CSS:
>
> #navigation:hover a {color: #000;}


Awesome - thanks!
 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      06-07-2009
Please attribute quotation(s) to their author(s).
vvvvvvvvvvv
Krys wrote:
>> No javascript required, just a little bit of CSS:
>>
>> #navigation:hover a {color: #000;}

>
> Awesome - thanks!


Except that it doesn't work with IE 6, and not properly in all cases with
IE 7, and IE 8 in Compatibility Mode (I did not care about its "Standards"
Mode yet), which some of us still need to support.

As far as I am concerned, the reliable implementation of non-`a'
element-related hover effects (like here) in Internet Explorer is a long and
sad story, so far without a happy ending. You can start by reading here:

<http://pointedears.de/scripts/test/dom/hoverMe/>

In particular, I had to notice recently that even those related target
checks (thanks to the person here who recommended performing them) are
insufficient when it comes to hovering over a `li' that has padding and
contains `h2' and `p' with margins (that is, div>li>h2 and div>li> p).

I'm not sure if the following is the last word on the subject, but it WFM as
good as I currently think it can. I couldn't avoid yet some blinking when
moving the pointer from one 1.5em-heighted line of the `p' to another line,
and from the `p' to the `h2'.

var jsx = {
// ...

object: {
// ...

/**
* Retrieves the value of a property.
*
* @param o : Object
* @param sProperty : string
* @param aDefault : mixed
* @return mixed
* @throw
* <code>jsx.object.</code>{@link PropertyError} if the property
* does not exist or has the <code>undefined</code> value, and
* <var>aDefault</var> was not provided
*/
getProperty: function(o, sProperty, aDefault) {
if (typeof o[sProperty] != "undefined")
{
return o[sProperty];
}

/* default value not passed */
if (arguments.length < 3)
{
jsx.throwThis(this.PropertyError, sProperty);
}

return aDefault;
},
};

jsx.dom = {
// ...

isAncestor:
/**
* @param o : Element
* @param o2 : Element
* @type boolean
* @return <code>true</code>, if <code>o</code> refers to an element
* object representing the ancestor element of the element
* represented by the object <code>o2</code> refers to;
* <code>false</code> otherwise.
*/
function(o, o2) {
if (o && o2)
{
while ((o2 = o2.parentNode))
{
if (o2 == o) return true;
}
}

return false;
},

/**
* Adds a CSS class name to the <code>class</code> attribute of
* an {@link Element}.
*
* @param o : Element
* @param sClassName : string
* @param bRemove : boolean
* If the class name is already there, and this argument is
* <code>true</code>, all instances of it are removed first.
* If the class is there and this argument is <code>false</code>,
* exit without changing anything. The default is <code>false</code>,
* which is more efficient.
*/
addClassName:
function(o, sClassName, bRemove) {
var rx = new RegExp("(^\\s*|\\s+)" + sClassName + "(\s*$|(\\s))");

if (bRemove)
{
this.removeClassName(o, sClassName);
}
else if (rx.test(o.className))
{
return;
}

if (/\S/.test(o.className))
{
o.className += " " + sClassName;
}
else
{
o.className = sClassName;
}
},

/**
* Removes all occurences of a CSS class name from the
* <code>class</code> attribute of an {@link Element}.
*
* @param o : Element
* @param sClass : string
*/
removeClassName:
function(o, sClassName) {
var curClassNames = o.className;
var newClassNames = curClassNames.replace(
new RegExp("(^\\s*|\\s+)" + sClassName + "(\s*$|(\\s))", "g"),
"$3");
o.className = newClassNames;
}

// ...
};

/**
* Custom hover function. Adds/removes the "hover" class
* from the class attribute of the primary target.
*
* @param e : Event
* @param o : Element
* @return boolean
*/
function hoverFunc(e, o)
{
var jsx_object = jsx.object;
var jsx_dom = jsx.dom;

if (o)
{
var
relatedTarget = jsx_object.getProperty(e, "relatedTarget", null),
currentTarget = jsx_object.getProperty(e, "currentTarget", null);

if (!(relatedTarget && currentTarget))
{
currentTarget = jsx_object.getProperty(e, "srcElement", null);

if (e.type == "mouseover")
{
relatedTarget = jsx_object.getProperty(e, "fromElement", null);
//var isRelated = jsx_dom.isAncestor(currentTarget, relatedTarget);
}
else if (e.type == "mouseout")
{
relatedTarget = jsx_object.getProperty(e, "toElement", null);
var isRelated = jsx_dom.isAncestor(
o, jsx_object.getProperty(e, "fromElement", null));
}
}

if (!relatedTarget || !currentTarget || currentTarget == relatedTarget
|| isRelated)
{
return false;
}

if (e.type == "mouseover")
{
/* TODO: Does this even make sense? */
// var me = arguments.callee;
// if (typeof me.lastHover != "undefined" && me.lastHover != o)
// {
// /*
// * For quick pointer movements:
// * Leave only one element in hover-on state
// */
// me({type: "mouseout", currentTarget: o}, me.lastHover);
// }
//
// hoverFunc.lastHover = o;

jsx_dom.addClassName(o, "hover");
}
else if (e.type == "mouseout")
{
jsx_dom.removeClassName(o, "hover");
}
}

return true;
}

Questions, comments, solutions anyone?


Ceterum censeo Internet Explorer esse delendam.

PointedEars
 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      06-07-2009
Thomas 'PointedEars' Lahn wrote:
> <http://pointedears.de/scripts/test/dom/hoverMe/>
>
> In particular, I had to notice recently that even those related target
> checks (thanks to the person here who recommended performing them) are
> insufficient when it comes to hovering over a `li' that has padding and
> contains `h2' and `p' with margins (that is, div>li>h2 and div>li> p).


That's div > ul > li > h2 + p, of course.
 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      06-07-2009
kangax wrote:
> Thomas 'PointedEars' Lahn wrote:
>> /**
>> * Adds a CSS class name to the <code>class</code> attribute of
>> * an {@link Element}.
>> *
>> * @param o : Element
>> * @param sClassName : string
>> * @param bRemove : boolean
>> * If the class name is already there, and this argument is
>> * <code>true</code>, all instances of it are removed first.
>> * If the class is there and this argument is <code>false</code>,
>> * exit without changing anything. The default is <code>false</code>,
>> * which is more efficient.
>> */
>> addClassName:
>> function(o, sClassName, bRemove) {
>> var rx = new RegExp("(^\\s*|\\s+)" + sClassName + "(\s*$|(\\s))");

> ^^^^ ^^^ ^ ^
> Are those "extra" \s* meant to speed things up? Otherwise, they seem
> unnecessary.


They are meant to make it more reliable (a class name is already there if it
is followed by optional whitespace followed by the end of input, or followed
by mandatory whitespace), however it really should be "\\s*$" because of the
string.

> As well as those parens around last \s.


Unnecessary indeed, just copy-pasted from removeClassName() where they make
sense.

> On a side note, have you considered caching regex objects? I know that
> `new RegExp` is a pretty expensive operation in at least Firefox, so
> caching could speed things up substantially.


Considering the possible change in ES 5, and the cost involved looking up
the RegExp, that does not seem to make sense.


PointedEars
 
Reply With Quote
 
Jorge
Guest
Posts: n/a
 
      06-08-2009
On Jun 8, 1:39*am, kangax <(E-Mail Removed)> wrote:
>
> Just to clarify what I meant:
>
> var addClassName = (function(){
> * *var cache = {};
> * *return function(element, className) {
> * * *var re = cache[className]
> * * * *|| (cache[className] = new RegExp(
> * * * * *'(?:^|\\s+)' + className + '(?:\\s+|)$'));
> * * *...
> * *}
>
> })();


A memoizer... (*)

> (That `cache[className]` boolean check should probably be guarded
> against `Object.prototype` properties)


var addClassName = (function(){
var cache = {};
return function(element, className) {
var re = cache.hasOwnProperty(className) ? cache[className] :
(cache[className] = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|)
$'));

...
}
})();

(*) "JavaScript: The Good Parts", by Douglas Crockford, page 44.

--
Jorge.
 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      06-08-2009
kangax wrote:
> Thomas 'PointedEars' Lahn wrote:
>> kangax wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> /**
>>>> * Adds a CSS class name to the <code>class</code> attribute of
>>>> * an {@link Element}.
>>>> *
>>>> * @param o : Element
>>>> * @param sClassName : string
>>>> * @param bRemove : boolean
>>>> * If the class name is already there, and this argument is
>>>> * <code>true</code>, all instances of it are removed first.
>>>> * If the class is there and this argument is <code>false</code>,
>>>> * exit without changing anything. The default is <code>false</code>,
>>>> * which is more efficient.
>>>> */
>>>> addClassName:
>>>> function(o, sClassName, bRemove) {
>>>> var rx = new RegExp("(^\\s*|\\s+)" + sClassName + "(\s*$|(\\s))");
>>> ^^^^ ^^^ ^ ^
>>> Are those "extra" \s* meant to speed things up? Otherwise, they seem
>>> unnecessary.

>> They are meant to make it more reliable (a class name is already there if it
>> is followed by optional whitespace followed by the end of input, or followed
>> by mandatory whitespace), however it really should be "\\s*$" because of the
>> string.

>
> How are they more reliable than, say:
>
> new RegExp("(^|\\s+)" + sClassName + "(\\s+|$)");
>
> The only difference I see is that regex from your version will not enter
> second alteration in - (^\s*|\s+) - when matched against a string that
> starts with 1+ spaces (since ^\s* will succeed before).


You mean the second alternative of the first _alternation_.

<http://oreilly.com/catalog/regex/chapter/ch04.html>

> This is why I thought you made it like so for performance reasons.


That was not my intention. As I said, I copied the call from
removeClassName(). But I might test efficiency later.

>>> As well as those parens around last \s.

>> Unnecessary indeed, just copy-pasted from removeClassName() where they make
>> sense.
>>
>>> On a side note, have you considered caching regex objects? I know that
>>> `new RegExp` is a pretty expensive operation in at least Firefox, so
>>> caching could speed things up substantially.

>> Considering the possible change in ES 5, and the cost involved looking up
>> the RegExp, that does not seem to make sense.

>
> Which changes in ES5 are you talking about?


I confused the issues. In the ES 5 Final Draft, it says that RegExp
initializers, regardless of structure, represent a different RegExp object
each, while in ES 3 all RegExp initializers that are the same refer to the
same RegExp object. *That* is not an issue here as no initializers are used.

> And which cost is involved looking up the RegExp?
>
> Just to clarify what I meant:
>
> var addClassName = (function(){
> var cache = {};
> return function(element, className) {
> var re = cache[className]
> || (cache[className] = new RegExp(
> '(?:^|\\s+)' + className + '(?:\\s+|)$'));
> ...
> }
> })();


However, caching RegExp objects like this carries with it the possibility
that the matcher will not start at the beginning of input but at the last
matched position. And:

> (That `cache[className]` boolean check should probably be guarded
> against `Object.prototype` properties)


It needs to be guarded against much more than that, cf. my Map()
implementation. And those precautions are what makes the lookup probably
more expensive than what the avoided RegExp() call is worth.


PointedEars
 
Reply With Quote
 
Jorge
Guest
Posts: n/a
 
      06-08-2009
On Jun 8, 4:16*am, kangax <(E-Mail Removed)> wrote:
> (..)
> I wish it was that easy
>
> ({}).hasOwnProperty('__proto__'); // true in FF3.x


Ahh, that... of course ! (in Safari as well). Hopefully this is going
to help

"Object.create will allow a null prototype. This is very useful for
making pure hash table objects."
https://mail.mozilla.org/pipermail/e...ay/002691.html

--
Jorge.
 
Reply With Quote
 
 
 
Reply

Thread Tools

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 On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Change href color on hover? Ken Williams HTML 3 05-03-2011 02:42 PM
getting columns to change color on hover Rahul HTML 7 07-24-2009 09:38 PM
link hover color not honored when using onclick event Richard Thoms HTML 6 12-02-2005 02:55 AM
NS/FF don't change div offsetWidth when div innerHTML is added toand div becomes wider mscir Javascript 3 06-26-2005 04:04 PM
Change cell color when hover VB Programmer ASP .Net 3 06-11-2004 10:09 PM



Advertisments