pseudo classe :hover - IE6, UpdatePanel et csshover.htc
CSS permet de définir des pseudos classes, il y a notamment la pseudo classe :hover qui s'applique seulement lorsqu'on passe la souris sur l'élément. On utilise couramment cette technique pour faire des menus, j'avais d'ailleurs fait le menu de la version 8 de CodeS-SourceS ainsi et même un article expliquant les règles CSS utilisés. Le gros problème de ces pseudos classe c'est qu'elles ne sont pas prises en compte par IE6. Il existe cependant un behavior htc qui permet de faire comprendre à IE6 les pseudos règles :hover, :active et :focus : csshover.htc
Pour rajouter le csshover.htc, il faut utiliser cette syntaxe.
* html body {
behavior:url(csshover.htc);
}
span:hover {
color:#F0F;
}
Ainsi à chaque fois que la souris passe sur un span, la couleur du texte change, même sous IE6. Le problème est que le csshover.htc fonctionne seulement sur les éléments présents à l'origine du document. Si vous modifier le DOM après le chargement de la feuille de style alors IE6 ne prendra plus en compte le :hover sur les nouveaux éléments.
Ainsi, dans l'exemple ci-dessous, le span ne changera pas de couleur après avoir cliquer sur le bouton :
<asp:ScriptManager runat="server" />
<asp:UpdatePanel runat="server">
<ContentTemplate>
<span>pouet</span>
<asp:Button runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
Ma première idée a été de modifier le fichier csshover.htc, notamment la fonction parseStylesheets :
// this solution doesn't work !
var firstCall = true;
function parseStylesheets() {
if(!/MSIE (5|6)/.test(navigator.userAgent)) return;
if (firstCall){
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(function(sender, args){
if (args.get_isPartialLoad())
parseStylesheets();
});
}
firstCall = false;
window.attachEvent('onunload', unhookHoverEvents);
var sheets = doc.styleSheets, l = sheets.length;
for(var i=0; i<l; i++)
parseStylesheet(sheets[ i ]);
}
Malheureusement il est impossible de passer un objet Function vers le contexte de la page ! Je n'ai rien trouvé sur le net qui explique le problème. Si quelqu'un a une explication, je suis preneur.
Ma seconde idée est d'utiliser window.setTimeout pour relancer la fonction à intervalle régulier :
function parseStylesheets() {
if(!/MSIE (5|6)/.test(navigator.userAgent)) return;
window.attachEvent('onunload', unhookHoverEvents);
var sheets = doc.styleSheets, l = sheets.length;
for(var i=0; i<l; i++)
parseStylesheet(sheets[ i ]);
window.setTimeout(parseStylesheets, 1000);
}
[Update] : On peut bien sur optimiser cette solution, mais suite aux commentaires de FremyCompany, voici une solution bien plus propre que ce je proposais. Il faut mettre la fonction parseStylessheets dans l'objet window.
var firstCall = true;
function parseStylesheets() {
if(!/MSIE (5|6)/.test(navigator.userAgent)) return;
var sheets = doc.styleSheets, l = sheets.length;
if(firstCall){
window.attachEvent('onunload', unhookHoverEvents);
window.parseStylesheets = parseStylesheets;
firstCall = false;
} else {
hoverEvents = [];
unhookHoverEvents();
}
for(var i=0; i<l; i++)
parseStylesheet(sheets[ i ]);
}
Puis dans votre page rajouter
window.pageLoad = function(sender, args){
if (args.get_isPartialLoad() && window.checkParseStylesheets){
window.checkParseStylesheets()
}
}
Si vous utiliser un script externe, je vous conseille de passer par cette syntaxe :
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(function(sender, args){
if (args.get_isPartialLoad() && window.checkParseStylesheets){
window.checkParseStylesheets()
}
});
Cette solution vous permettra, en un minimum de temps, de rendre votre application web compatible avec ce vieux navigateur qui reste malheureusement beaucoup trop utilisés.