Please attribute quotation(s) to their author(s).
vvvvvvvvvvv said:
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