Voir le flux RSS

danielhagnoul

Création d'un objet à partir d'un fragment du DOM

Noter ce billet
par , 27/11/2014 à 21h06 (847 Affichages)
Il n'est pas rare de voir une débauche de nom de classes et d'ID dans un code HTML, particulièrement lorsqu'il s'agit des éléments d'un formulaire. On constatera souvent un usage partiel de cette panoplie de sélecteurs, mais on vous répondra qu'il faut prévoir les usages futurs.

En pratiquant de cette manière on alourdit le code HTML et en JS on grève les performances en multipliant les constructions de sélecteurs. Chaque construction exigeant un parcours, plus ou moins rapide, de l'arbre du DOM.

Certes, il existe pléthore de méthodes pour parcourir les nœuds d'un arbre DOM à partir d'un nœud parent. On peut donc construire tous nos sélecteurs à partir d'un seul ID. Mais on n'améliorera pas les performances en déplaçant le problème.

Nous allons voir comment, à partir d'un seul ID, on peut disposer de notre panoplie de sélecteurs en parcourant une seule fois l'arbre d'un fragment du DOM.

Fragment du DOM

Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
<div id="formulaire">
    <input type="text" value="inconnu">
    <select>
        <option value="inconnu">0</option>
        <option value="Henri">1</option>
        <option value="Pierre">2</option>
        <option value="Daniel">3</option>
        <option value="Jean">4</option>
    </select>   
</div>

Fonction createDOMObject( domFragment, keys, boolChildren )

  • domFragment : un fragment du DOM
  • keys : un array contenant le nom des propriétés de l'objet. Si l'array ne contient pas assez de valeur, on utilise le numéro d'index des éléments du DOM.
  • boolChildren : doit-on prendre en compte les enfants des éléments du DOM contenus dans domFragment ? Valeur false par défaut.


On utilise les fonctions getType() et setModel() des billets précédents.

Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
$( function( ){
 
    function getType( Obj ){
        return Object.prototype.toString.call( Obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase();
    }
 
    function setModel( Obj ){
        if ( getType( Obj ) === "object" ){
            Obj[ "_objectModel" ] = Object.create( Object.prototype );
            Object.getOwnPropertyNames( Obj ).forEach( function( key ){
                if ( key != "_objectModel" ) {
                    Object.defineProperty( Obj[ "_objectModel" ], key, {
                        "value" : getType( Obj[ key ] ),
                        "enumerable" : true
                    });
                }
            });
        } else {
            throw "Erreur dans setModel(), " + Obj + " n'est pas un objet";
        }
    }
 
    function createDOMObject( domFragment, keys, boolChildren ){
        var Obj = Object.create( Object.prototype ),
            nodes = [],
            treeWalker = null,
            bool = boolChildren || false;
 
        if ( getType( domFragment ).slice( 0, 4 ) === "html" ) {
 
            treeWalker = document.createTreeWalker(
                domFragment,
                NodeFilter.SHOW_ELEMENT,
                {
                    "acceptNode" : function( node ){
                        if ( bool ) {
                            return NodeFilter.FILTER_ACCEPT;
                        } else if ( node.parentNode === domFragment ) {
                            return NodeFilter.FILTER_ACCEPT;
                        }
 
                        return NodeFilter.FILTER_SKIP;
                    }
                },
                false
            );
 
            while( treeWalker.nextNode() ){
                nodes.push( treeWalker.currentNode );
            }
 
            nodes.forEach( function( item, i ){
                var key = "dom_" + (  keys[ i ] ? keys[ i ] : i );
 
                Object.defineProperty( Obj, key, {
                    "value" : item,
                    "enumerable" : true
                });
            });
        } else {
            alert( "L'objet créé est vide, car le paramètre domFragment ne contient pas un fragment du DOM" );
        }
 
        return Obj;
    }
 
    /*
     * Construction d'un objet à partir d'un fragment du DOM
     *
     * JS : document.querySelector( "#formulaire" )
     * jQuery : $( "#formulaire" )[ 0 ]
     */
    var Formulaire = createDOMObject( document.querySelector( "#formulaire" ), [ "prenom", "choix" ] );
 
    /*
     * Ajout du modèle de type
     */
    setModel( Formulaire );
 
    console.log( Formulaire );
 
    /*
     * _objectModel:
     *   dom_choix: "htmlselectelement"
     *   dom_prenom: "htmlinputelement"
     * dom_choix: select
     * dom_prenom: input
     */
 
});

Envoyer le billet « Création d'un objet à partir d'un fragment du DOM » dans le blog Viadeo Envoyer le billet « Création d'un objet à partir d'un fragment du DOM » dans le blog Twitter Envoyer le billet « Création d'un objet à partir d'un fragment du DOM » dans le blog Google Envoyer le billet « Création d'un objet à partir d'un fragment du DOM » dans le blog Facebook Envoyer le billet « Création d'un objet à partir d'un fragment du DOM » dans le blog Digg Envoyer le billet « Création d'un objet à partir d'un fragment du DOM » dans le blog Delicious Envoyer le billet « Création d'un objet à partir d'un fragment du DOM » dans le blog MySpace Envoyer le billet « Création d'un objet à partir d'un fragment du DOM » dans le blog Yahoo

Mis à jour 07/06/2015 à 11h57 par danielhagnoul

Catégories
Javascript , Développement Web

Commentaires