IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

[Article] Virtualisation de pages web en DOM


Sujet :

JavaScript

  1. #1
    Membre éclairé

    Femme Profil pro
    Experte JS / Conseillère en best practices / Chercheuse en programmation
    Inscrit en
    Octobre 2007
    Messages
    740
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Experte JS / Conseillère en best practices / Chercheuse en programmation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 740
    Points : 805
    Points
    805
    Par défaut [Article] Virtualisation de pages web en DOM
    Bonjour à tous,

    Voici l'ébauche de mon véritable premier article.

    ####################################################

    Virtualisation de pages web en DOM

    En Javascript/AJAX, vous aurez sûrement déjà rencontré l'impossibilité pour l'utilisateur d'employer les fonctions "page précédente" et "page suivante".

    Bien entendu, il existe des solutions jouant sur le hash mais ce n'est pas le cadre de ce sujet.

    Je vais vous présenter une solution DOM, elle n'est pas correctement gérée par les navigateurs mais je la trouve plus qu'intéressante et espère que son implémentation sera corrigée par les concepteurs de navigateurs.

    Vous ne le saviez peut-être pas mais votre navigateur n'enregistre pas que l'url des pages que vous visitez, en effet, il enregistre aussi l'état DOM de ces pages.

    Pour tester le code présent dans cet article, je vous conseille d'utiliser Firefox, navigateur qui semble au plus proche d'une gestion totale.

    Les méthodes que nous allons utiliser à cet effet sont :

    document.open([MIMEtype [, historyPosition]]), elle sert à ouvrir un nouveau document dans l'onglet courant, ce qui ajoutera une nouvelle entrée à l'historique du navigateur. En théorie, il devrait être possible d'ajouter cette nouvelle entrée à une position déterminée, dans l'historique, mais nous ne l'emploierons pas, par respect de l'environnement de notre visiteur et afin de simuler la navigation classique.

    document.writeln(text), servant à écrire dans le document courant.

    document.close(), pour fermer le chargement du document.


    Mise en pratique

    Prenez une page web classique avec un bouton:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    	<head>
    		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    		<title>Previous/Next DOM sample</title>
    	</head>
    	<body>
    		<button>goTo</button>
    	</body>
    </html>
    Ouvrons un document virtuel en Javascript :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    // La fonction ouvrant un document virtuel
    function goTo(){
    	document.open('text/html');
    	document.close();
    }
    // Attachons cette fonction au clic sur notre bouton
    document.getElementsByTagName('button')[0].onclick=goTo;
    La base est établie mais il serait bien de travailler avec un document valide :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function goTo(){
    	document.open('text/html');
    	// Ajoutons-y la déclaration XML
    	document.writeln('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
    	// Ainsi qu'un doctype
    	document.writeln('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">');
    	document.close();
    }
    document.getElementsByTagName('button')[0].onclick=goTo;
    À présent, une petit peu de contenu pour illustrer l'exemple et, puisque nous avions déjà du code présent dans la page, autant le réutiliser :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    function goTo(){
    	// Sauvegardons le contenu du document courant, avant de le modifier
    	var root=document.getElementsByTagName('html')[0];
    	document.open('text/html');
    	document.writeln('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
    	document.writeln('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">');
    	// Ajoutons le contenu sauvegardé au document virtuel
    	document.appendChild(root);
    	document.close();
    }
    document.getElementsByTagName('button')[0].onclick=goTo;
    Testez l'exemple, en ne cliquant qu'une seule fois sur le bouton (sous peine de déclencher une exception "attempt to run compile-and-go script on a cleared scope" qui provoquera un "page précédente" infini) et observez le comportement du navigateur.

    Il y a bien un nouveau chargement et le bouton "page précédente" est devenu actif, cqfd!

    Un petit effet visuel, afin de mieux voir ce qui se passe réellement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    // Définissons une couleur d'origine pour le bouton
    document.getElementsByTagName('button')[0].style.color='red';
    function goTo(){
    	var root=document.getElementsByTagName('html')[0],button;
    	document.open('text/html');
    	document.writeln('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
    	document.appendChild(root);
    	// Récupérons notre bouton
    	button=document.getElementsByTagName('button')[0];
    	// Modifions sa couleur, en fonction de la couleur qu'il avait précédemment
    	button.style.color=button.style.color=='red'?'green':button.style.color=='green'?'blue':'red';
    	document.close();
    }
    document.getElementsByTagName('button')[0].onclick=goTo;
    Revenons sur l'exception déclenchée par Firefox lorsque l'on clique plusieurs fois sur le bouton.

    Il semble, d'après mes tests, que window est remis à neuf au chargement du document virtuel, néanmoins, je soupçonne le navigateur de conserver des références qu'un document qui n'existe plus, nous allons donc les redéfinir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    document.getElementsByTagName('button')[0].style.color='red';
    function goTo(){
    	// Sauvegardons notre fonction goTo
    	var root=document.getElementsByTagName('html')[0],button,tmp=window.goTo;
    	document.open('text/html');
    	document.writeln('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
    	document.appendChild(root);
    	button=document.getElementsByTagName('button')[0];
    	button.style.color=button.style.color=='red'?'green':button.style.color=='green'?'blue':'red';
    	document.close();
    	// Redéclarons notre fonction goTo
    	window.goTo=tmp;
    }
    document.getElementsByTagName('button')[0].onclick=goTo;
    Voilà, réessayez ce code et vous observerez qu'il est désormais possible de naviguer au sein de documents virtuels avec les boutons "page précédente" et "page suivante".

    Les bémols

    Le navigateur semble ne conserver que le dernier état du DOM, impossible donc, actuellement, de baser la navigation d'une application web sur ce système.

    Quid des autres navigateurs?

    IE 9 :
    Amnésie? Il ne semble pas possible de "sauvegarder" l'arbre DOM, pour le reconstituer, après document.open(). IE se rappelle bien du type d'objet (node) mais, par exemple, pas de son tagName.

    Google Chrome 14 :
    Ne semble pas stocker l'état du DOM et pré-remplit le document avec des noeuds HTML.


    ####################################################

    Je vous invite à me faire part des vos avis, conseils/critiques et vous en remercie d'avance.
    Afin d'obtenir plus facilement de l'aide, n'hésitez pas à poster votre code de carte bancaire

    Mon GitHub

    Une alternative à jQuery, Angular, Vue.js, React, ... ? Testez anticore, en quelques secondes à peine !
    (Contributions bienvenues)

  2. #2
    Membre éprouvé
    Avatar de Gecko
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Décembre 2008
    Messages
    499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Décembre 2008
    Messages : 499
    Points : 1 277
    Points
    1 277
    Par défaut
    Comme je viens de te le dire sur le chat, je trouve que ton article est intéressant mais qu'il manque de démo.

    C'est balo de mettre des sources dedans et de ne pas montrer le résultat en live

    Cordialement Toine
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($toBe || !$toBe) echo 'That is the question';

    Mes projets: DVP I/O

  3. #3
    Membre expérimenté Avatar de Willpower
    Homme Profil pro
    sans emploi
    Inscrit en
    Décembre 2010
    Messages
    1 009
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : sans emploi

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 009
    Points : 1 519
    Points
    1 519
    Par défaut
    J'avoue ne pas m'y connaitre là-dedans (document.open etc..) mais ton article a au moins le mérite d'avoir éveillé ma curiosité.
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    eval(a='eval(a)')
    recursive make it evil
    eval make it eval

Discussions similaires

  1. DOM : récupérer un élément d'une page web
    Par thibaud74 dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 16/07/2010, 13h35
  2. Obtenir le DOM d'une page web
    Par Nico B. dans le forum VBScript
    Réponses: 0
    Dernier message: 28/05/2010, 13h21
  3. [DOM] Ajouter une DIV dans une page web
    Par Nulenprogra dans le forum Général JavaScript
    Réponses: 13
    Dernier message: 19/09/2007, 17h48
  4. Réponses: 15
    Dernier message: 24/05/2007, 13h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo