Page 1 sur 2
Javascript dégradable, <yesscript> ?
Posté : 17 févr. 2008, 22:10
par Hubert Roksor
Oh, hai.
On sait qu'il est de bon ton de faire du Javascript dégradable, c'est-à-dire qui interfère le moins possible avec le bon déroulement d'une page, qu'il soit activé ou non. On connait la balise <noscript> qui permet d'afficher du contenu uniquement aux utilisateurs ayant
désactivé Javascript. Mais comment afficher du contenu uniquement aux utilisateurs l'ayant
activé ?
À l'heure actuelle, mon cœur penche vers ceci, à place entre les balises <head> de votre document :
Code : Tout sélectionner
<style type="text/css" id="degradable_js_stylesheet">
.js_required
{
display: none;
}
</style>
<script type="text/javascript">
var stylesheet = document.getElementById('degradable_js_stylesheet');
stylesheet.parentNode.removeChild(stylesheet);
</script>
Le principe étant de d'ajouter la classe "js_required" à tous les éléments à cacher si Javascript est désactivé, de tous les cacher par CSS et annuler cet ordre par Javascript le plus tôt possible pour éviter d'avoir un effet de clignotement au moment du chargement de la page.
Pendant un moment j'avais pensé mettre le <style> entre des balises <noscript> mais ce n'est pas permis par HTML. Est-ce que quelqu'un aurait devisé une méthode plus pratique ou performante ? Je suis tout ouïe, merci

Posté : 17 févr. 2008, 22:37
par Sékiltoyai
Un document.write() ?
Posté : 17 févr. 2008, 22:48
par Victor BRITO
Pour ma part, je pencherais sur l'ajout d'une classe à chaque élément qu'on souhaite masquer en JavaScript. En JavaScript, il suffirait de boucler chaque élément et d'ajouter le style display: none chaque fois qu'on trouve le nom de la classe cherchée.
Posté : 18 févr. 2008, 00:04
par Hubert Roksor
Un document.write() ?
L'embêtant d'un document.write() (ou des appels d'appendChild, innerHTML, etc...) c'est que c'est relativement lent et ça force à mélanger HTML et Javascript. Ça interfère également avec le processus de validation du document.
Pour ma part, je pencherais sur l'ajout d'une classe à chaque élément qu'on souhaite masquer en JavaScript. En JavaScript, il suffirait de boucler chaque élément et d'ajouter le style display: none chaque fois qu'on trouve le nom de la classe cherchée.
Le principe est de faire
apparaître les éléments nécessitant Javascript, et dans ce cas il faudrait faire un "display:block" ou plutôt retirer la valeur de l'attribut "display" pour lui faire adopter sa valeur par défaut et ne pas interférer avec les éléments inline. Malheureusement, ça voudrait dire qu'il faut faire une boucle sur tous les éléments de la page, donc ça peut prendre un petit peu de temps. De plus, cette boucle ne pourrait être exécutée qu'une fois le DOM complètement chargé et probablement déjà au moins partiellement affiché. C'est pourquoi j'ai opté pour un script que l'on peut placer le plus haut possible dans le document, de façon à minimiser le nombre de repaint/reflow.
Je ne l'ai pas précisé, mais j'ai aussi essayé de modifier le CSS via l'interface DOM, mais c'est plus long à taper et comme toujours la gymnastique pour le faire fonctionner sous IE est très désagréable.
Pour l'heure, retirer ce stylesheet spécial par removeChild() semble est la solution la plus rapide et la plus simple, mais si vous avez d'autres idées n'hésitez pas !

Posté : 18 févr. 2008, 02:12
par AB
Je prend note.
Jusqu'à présent je n'avais à gérer qu'un bloc ou deux donc je faisais :
Code : Tout sélectionner
<body onload="document.getElementById().style.display = 'block' ;">
après les avoir cachés par CSS
Pour plus d'un bloc ta solution me parait tip top

Posté : 18 févr. 2008, 10:50
par Hywan
À propos de rapidité, tu devrais jeter un oeil sur l'
intégration native de certaines fonctions Javascript comme getElementsByClassName pour WebKit. Apparemment, ce procédé devrait s'étendre à plusieurs navigateurs par la suite tellement les résultats sont autrement performants.
Edit : les commentaires sont également intéressants

.
Posté : 18 févr. 2008, 13:29
par AB
À propos de rapidité, tu devrais jeter un oeil sur l'
intégration native de certaines fonctions Javascript comme getElementsByClassName pour WebKit. Apparemment, ce procédé devrait s'étendre à plusieurs navigateurs par la suite tellement les résultats autrement performants.
Edit : les commentaires sont également intéressants

.
On l'aura attendue longtemps cette fonction... Et le temps que les utilisateurs aient tous des navigateurs qui la supportent, les solutions comme celle d'Hubert ont encore de longues années devant elles

Posté : 18 févr. 2008, 22:51
par naholyr
Je procède comme ça aussi, j'utilise ce genre de choses en général :
Javascript
Code : Tout sélectionner
Event.observe(window, "load", function(){
$A(document.getElementsByTagName("yesscript")).each(function(element){
element.show();
});
});
HTML
Code : Tout sélectionner
<span class="yesscript">Only si tu as enablé Javascript my buddy-friend :)</span>
Posté : 19 févr. 2008, 11:06
par Hywan
À propos de rapidité, tu devrais jeter un oeil sur l'
intégration native de certaines fonctions Javascript comme getElementsByClassName pour WebKit. Apparemment, ce procédé devrait s'étendre à plusieurs navigateurs par la suite tellement les résultats autrement performants.
Edit : les commentaires sont également intéressants

.
On l'aura attendue longtemps cette fonction... Et le temps que les utilisateurs aient tous des navigateurs qui la supportent, les solutions comme celle d'Hubert ont encore de longues années devant elles

Ça arrivera plus vite que tu ne le crois

. Si WebKit l'implémente, alors Safari et Konqueror l'auront. Firefox est séduit par ces résultats, peut-être pour la bêta 4 de ffx 3 ? Non j'en doute, mais pour Firefox v4, il y a de forte probabilité pour que ça arrive. Comptons alors 2 ans maximum.
Et pour IE ... euh c'est quoi déjà comme logiciel ça ?
On notera au passage que XPath est plus rapide que DOM. Comme Hubert s'intéressait à XML la dernière fois, tu peux sûrement savoir si XPath est activé côté client (navigateur), car les résultats sont sensiblement plus performants.
Posté : 19 févr. 2008, 11:16
par Hubert Roksor
À ma connaissance, à peu près tous les navigateurs proposent XPath. Le problème d'XPath étant qu'il est super-relou à utiliser en JS

[edit: ah ben non, moins que dans mes souvenirs. En tout cas, dans les navigateurs récents]
Ceci dit, comme je le disais plus haut, les solutions à base de getElementsByTagName() ont le désavantage de nécessiter d'attendre que le DOM soit complétement chargé et peuvent potentiellement entrainer plusieurs reflow puisque chaque élément est modifié séparément, c'est pourquoi je m'oriente vers quelque chose qui puisse être placé dans le <head>. D'après ce que j'ai pu voir sur les navigateurs à ma disposition, ma solution actuelle pourrait être la meilleure, mais je reste vigilant et n'écarte pas la possibilité que l'on trouve un moyen plus pratique.
Posté : 24 févr. 2008, 17:10
par Hywan
Si XPath est moins ch*ant à utiliser, et qu'il ne nécessite pas que le DOM soit chargé, ne serait-il pas préférable de le préférer à getElementsByTagName() ?
Posté : 24 févr. 2008, 17:26
par Hubert Roksor
Comme pour getElementsByTagName(), tu dois attendre d'avoir chargé le DOM pour utiliser XPath. Tu peux utiliser l'un comme l'autre dans <head /> mais ça ne servirait à rien puisque le document n'a même pas de <body /> à ce moment là.
...d'où l'approche actuelle consistant à virer du document cet élément <style /> avant même d'avoir commencé à peindre la page.
Posté : 02 nov. 2008, 18:41
par AB
J'avais gardé cette astuce dans mes cartons ...
On peut également utiliser ce script (premier post donné par Hubert) pour cacher des éléments pour les seuls navigateurs ayant JS activé.
C'est très pratique quand on doit modifier des styles css sans attendre le chargement de la page, et sans avoir à modifier les styles Css via javascript (ce qui peut s'avérer pénible et délicat pour être compatible avec la majorité des navigateurs).
Code : Tout sélectionner
<style type="text/css">
.cachetext {
visibility:hidden;
}
</style>
<style type="text/css" id="degradable_js_stylesheet">
.affichetext {
visibility:visible;
}
</style>
<script type="text/javascript">
var stylesheet = document.getElementById('degradable_js_stylesheet');
stylesheet.parentNode.removeChild(stylesheet);
</script>
//... HTML
<div class = "cachetext affichetext">Contenu</div>
Gros avantage : la simplicité et la compatibilité du code avec quasiment tous les navigateurs.
Le seul tout petit problème : cette syntaxe n'est pas valide XHTML 1.1 mais "seulement" XHTML 1.0 scrict.
Posté : 02 nov. 2008, 22:11
par Hywan
Hey

,
On préférera utiliser
display à
visibility en revanche.
Et je ne comprends pas pourquoi ce n'est pas valide XHTML 1.1 ?
Posté : 02 nov. 2008, 22:29
par AB
Hey

,
On préférera utiliser
display à
visibility en revanche.
Et je ne comprends pas pourquoi ce n'est pas valide XHTML 1.1 ?
Taratata... on préférera utiliser ce que l'on veux suivant les circonstances. La propriété "visibility" ayant l'avantage de réserver les dimensions du bloc, ce qui peut être utile dans certains cas.
Concernant la non validation en XHTML 1.1, le validateur dit qu'il ne doit pas y avoir d'id dans une balise <style type="text/css"...
Maintenant si tu me demandes pourquoi ils ont décidé ça ... bah on va rentrer dans le conceptuel du comment du pourquoi. Et pour m'être penché à quelques reprises sur ce genre de décisions, je te laisse volontiers la suite
