30 May, 2009
Alles:hover, :active, :focus voor IE6
Categoriën: crossbrowser |IE6 |javascript |Non Valid |solution
De CSS pseudo eigenschap :hover werkt in Internet Explorer alleen op de <a> tag, alle andere browsers laten je toe deze eigenschap toe te passen op alle HTML elementen. Met volgende JavaScript oplossingen kun je Internet Explorer 6 deze eigenschap ook toekennen.
:active en :focus zijn niet bekend voor IE6, dit script lost dit eveneens op.
HTML
<ul id="menu">
<li><a href="#"> lorem </a></li>
<li class="folder">
<a class="submenu" href="#"> adipiscing </a>
<ul>
<li><a href="#"> dolor </a></li>
<li class="folder">
<a class="submenu" href="#"> consectetuer</a>
<ul>
<li><a href="#"> elit </a></li>
<li><a href="#"> ipsum </a></li>
<li><a href="#"> Donec </a></li>
</ul>
</li>
<li><a href="#"> vestibulum </a></li>
</ul>
</li>
<li class="folder">
<a class="submenu" href="#"> consectetuer</a>
<ul>
<li><a href="#"> elit </a></li>
<li><a href="#"> ipsum </a></li>
<li><a href="#"> Donec </a></li>
</ul>
</li>
<li><a href="#"> sit amet </a></li>
</ul>
CSS
body {
behavior: url("csshover3.htc");
}
ul, li, a {
margin:0;
padding:0;
border:0;
}
ul {
width:150px;
border:1px solid #9d9da1;
background:white;
list-style:none;
display:block;
margin:0;
padding:0;
}
li {
position:relative;
padding:1px;
font-size: 1.2em;
padding-left:26px;
background:url("images/item_moz.gif") no-repeat;
z-index:9;
display:block;
}
li.folder { background:url("images/item_folder.gif") no-repeat; }
li.folder ul {
position:absolute;
left:120px; /* IE */
top:5px;
}
li.folder>ul { left:140px; } /* others */
ul a {
padding:2px;
border:1px solid white;
text-decoration:none;
display:block;
color:gray;
font-weight:bold;
width:100%; /* IE */
}
li>a { width:auto; } /* others */
li a.submenu {
background:url("images/sub.gif") right no-repeat;
}
ul a:hover {
border-color:gray;
background-color:#bbb7c7;
color:black;
}
li.folder a:hover {
background-color:#bbb7c7;
}
li.folder:hover { z-index:10; }
ul ul, li:hover ul ul {
display:none;
}
li:hover ul, li:hover li:hover ul {
display:block;
}
Sla volgende complete code op in een bestand met extensie .htc
JavaScript/HTC
<public:attach event="ondocumentready" onevent="CSSHover()" />
<script>
//<?)|(a([^#.][^ ]+)+)):(hover|active|focus))/i,
REG_AFFECTED = /(.*?)\:(hover|active|focus)/i,
REG_PSEUDO = /[^:]+:([a-z-]+).*/i,
REG_SELECT = /(\.([a-z0-9_-]+):[a-z]+)|(:[a-z]+)/gi,
REG_CLASS = /\.([a-z0-9_-]*on(hover|active|focus))/i,
REG_MSIE = /msie (5|6|7)/i,
REG_COMPAT = /backcompat/i;
var CSSHOVER_PREFIX = 'csh-';
var CSSHover = {
elements: [],
callbacks: {},
init:function() {
// don't run in IE8 standards; expressions don't work in standards mode anyway,
// and the stuff we're trying to fix should already work properly
if(!REG_MSIE.test(navigator.userAgent) && !REG_COMPAT.test(window.document.compatMode)) return;
var sheets = window.document.styleSheets, l = sheets.length;
for(var i=0; i<l; i++) {
this.parseStylesheet(sheets[i]);
}
},
parseStylesheet:function(sheet) {
if(sheet.imports) {
try {
var imports = sheet.imports, l = imports.length;
for(var i=0; i<l; i++) {
this.parseStylesheet(sheet.imports[i]);
}
} catch(securityException){
}
}
try {
var rules = sheet.rules, l = rules.length;
for(var j=0; j<l; j++) {
this.parseCSSRule(rules[j], sheet);
}
} catch(securityException){
}
},
parseCSSRule:function(rule, sheet) {
var select = rule.selectorText;
if(REG_INTERACTIVE.test(select)) {
var style = rule.style.cssText,
// eg: "div li:hover" >> "div li"
affected = REG_AFFECTED.exec(select)[1],
// that pseudo is needed for a classname, and defines the type of interaction (focus, hover, active)
// eg: "li:hover" >> "onhover"
pseudo = select.replace(REG_PSEUDO, 'on$1'),
// the new selector is going to use that classname in a new css rule,
// since IE6 doesn't support multiple classnames, this is merged into one classname
// eg: "li:hover" >> "li.onhover", "li.folder:hover" >> "li.folderonhover"
newSelect = select.replace(REG_SELECT, '.$2' + pseudo),
className = REG_CLASS.exec(newSelect)[1];
var hash = affected + className;
if(!this.callbacks[hash]) {
sheet.addRule(affected, CSSHOVER_PREFIX + className + ':expression(CSSHover(this, "'+pseudo+'", "'+className+'"))');
this.callbacks[hash] = true;
}
sheet.addRule(newSelect, style);
}
},
patch:function(node, type, className) {
var property = CSSHOVER_PREFIX + className;
if(node.style[property]) {
node.style[property] = null;
}
if(!node.csshover) node.csshover = [];
if(!node.csshover[className]) {
node.csshover[className] = true;
var element = new CSSHoverElement(node, type, className);
this.elements.push(element);
}
return type;
},
unload:function() {
try {
var l = this.elements.length;
for(var i=0; i<l; i++) {
this.elements[i].unload();
}
this.elements = [];
this.callbacks = {};
} catch (e) {
}
}
};
window.attachEvent('onbeforeunload', function(){
CSSHover.unload();
});
var CSSEvents = {
onhover: { activator: 'onmouseenter', deactivator: 'onmouseleave' },
onactive: { activator: 'onmousedown', deactivator: 'onmouseup' },
onfocus: { activator: 'onfocus', deactivator: 'onblur' }
};
function CSSHoverElement(node, type, className) {
this.node = node;
this.type = type;
var replacer = new RegExp('(^|\\s)'+className+'(\\s|$)', 'g');
this.activator = function(){ node.className += ' ' + className; };
this.deactivator = function(){ node.className = node.className.replace(replacer, ' '); };
node.attachEvent(CSSEvents[type].activator, this.activator);
node.attachEvent(CSSEvents[type].deactivator, this.deactivator);
}
CSSHoverElement.prototype = {
unload:function() {
this.node.detachEvent(CSSEvents[this.type].activator, this.activator);
this.node.detachEvent(CSSEvents[this.type].deactivator, this.deactivator);
this.activator = null;
this.deactivator = null;
this.node = null;
this.type = null;
}
};
return function(node, type, className) {
if(node) {
return CSSHover.patch(node, type, className);
} else {
CSSHover.init();
}
};
})();
// ]]>
</script>
