Pages

Affichage des articles dont le libellé est DOM. Afficher tous les articles
Affichage des articles dont le libellé est DOM. Afficher tous les articles

Revision !

(function talksAbout(node, _string) {
     if ( --?-- )
        Array.from( node.childNodes ).forEach( function( node ) {
          talksAbout( node, _string  )
         });
     else if ( --?-- )
        if( node.nodeValue.indexOf( _string) > -1 )//.includes
           action;
})(document.body, "Dupont");


News version : cours DOM

Travail personel sur le DOM

Property / Method Description
element.appendChild() Adds a new child node, to an element, as the last child node
element.attributes Returns a NamedNodeMap of an element's attributes
element.childElementCount Returns the number of child elements an element has
element.childNodes Returns a collection of an element's child nodes (including text and comment nodes)
element.children Returns a collection of an element's child element (excluding text and comment nodes)
element.classList Returns the class name(s) of an element
element.className Sets or returns the value of the class attribute of an element
element.cloneNode() Clones an element
element.contains() Returns true if a node is a descendant of a node, otherwise false
element.contentEditable Sets or returns whether the content of an element is editable or not
element.firstChild Returns the first child node of an element
element.firstElementChild Returns the first child element of an element
element.getAttribute() Returns the specified attribute value of an element node
element.getAttributeNode() Returns the specified attribute node
element.getElementsByClassName() Returns a collection of all child elements with the specified class name
element.getElementsByTagName() Returns a collection of all child elements with the specified tag name
element.hasChildNodes() Returns true if an element has any child nodes, otherwise false
element.id Sets or returns the value of the id attribute of an element
element.innerHTML Sets or returns the content of an element
element.insertBefore() Inserts a new child node before a specified, existing, child node
element.lastChild Returns the last child node of an element
element.lastElementChild Returns the last child element of an element
element.nextSibling Returns the next node at the same node tree level
element.nextElementSibling Returns the next element at the same node tree level
element.nodeName Returns the name of a node
element.nodeType Returns the node type of a node
element.nodeValue Sets or returns the value of a node
element.parentNode Returns the parent node of an element
element.parentElement Returns the parent element node of an element
element.previousSibling Returns the previous node at the same node tree level
element.previousElementSibling Returns the previous element at the same node tree level
element.querySelector() Returns the first child element that matches a specified CSS selector(s) of an element
element.querySelectorAll() Returns all child elements that matches a specified CSS selector(s) of an element
element.removeAttribute() Removes a specified attribute from an element
element.removeChild() Removes a child node from an element
element.replaceChild() Replaces a child node in an element
element.setAttribute() Sets or changes the specified attribute, to the specified value
element.setAttributeNode() Sets or changes the specified attribute node
element.style Sets or returns the value of the style attribute of an element
element.tagName Returns the tag name of an element
element.textContent Sets or returns the textual content of a node and its descendants
nodelist.item() Returns the node at the specified index in a NodeList
nodelist.length Returns the number of nodes in a NodeList

TP : Afficher le nombre de chaque balise du DOM


Créer le code JS qui permet d'afficher le nombre de balises par type !

En action :

Injecter le code dans la console d'une page HTML prise au hasard.

Exemple :
Copier/coller puis exécuter le code directement dans la console du site le monde (ou autre) !
Si un message d'erreur apparaît relancer sur un autre fichier.


Besoin d'aide !

Etude du récursif en profondeur

Nous tentons de saisir encore une fois l'empilement des appels de fonctions dans le cas d'une fonction récursive.

Allez dans

http://dupontcours.free.fr/JavaScript/DOM-javascript/dom.html

Coller ce code dans la console.

let a=0,p =(e)=>{let a1=a++;console.groupCollapsed(`Begin ${e.nodeName} ${a1}`);Array.from(e.children,c=>p(c));console.log(`End ${e.nodeName} ${a1}`);console.groupEnd();};p(document.body);

Voici le déroulement des appels (nous devrions utiliser comme nous l'avons déjà fait le débogueur).

Etude de cas

Etude de la fonction findObj de MacroMedia dreamweaver
findObj on jsbin.com

parcours en profondeur

Nous allons étudier différents codes utilisant un parcours récursif.

L'idée est de parcourir le DOM à la recherche d'un item contenant un texte.
Si le nœud contient ce string on met le nœud en rouge.

Nous allons nous inspirer de la structure du code récursif pour parcourir le DOM

printDOM = (node, prefix) => {
  
    //action : affichage
  
    for(let nd of node.children) {
           printDOM ( nd, prefix + '-' );
     }
}
printDOM(document," ");


Remplaçons simplement action par :

 if (node.innerHTML.indexOf(string) > -1) {
         node.style.color="red";
       }
ce code met en rouge le noeud node contenant le mot string.

function find(node, string) {
       if (node.innerHTML.indexOf(string) > -1) {
         node.style.color="red";
       }
       for (n of node.children) {
          find(n, string);
       }
}

console.log(find(document.body, "para"));

Testez le code ;

  


Analyse : 

que vaut document.body.innerHTML.indexOf("second")
testez alors

       if (document.body.innerHTML.indexOf("second") > -1) {

         document.body.style.color="red";}

Passons à un code offrant une plus grande granularité sur les nœuds

Etudier le code suivant

function find(node, string) { if (node.nodeType == document.ELEMENT_NODE) { for (var i = 0; i < node.childNodes.length; i++) { if (find(node.childNodes[i], string)) return true; } return false; } else if (node.nodeType == document.TEXT_NODE) { if (node.nodeValue.indexOf(string) > -1) { alert("le HTLM contient le nom cherché"); return true; } return false; } }


coller le code suivant dans la console.

function find(node, string) {
    if (node.nodeType == document.ELEMENT_NODE) {
       for (var i = 0; i < node.childNodes.length; i++) {
          if (find(node.childNodes[i], string))
             return true;
          }
          return false;
    } else if (node.nodeType == document.TEXT_NODE) {
       if (node.nodeValue.indexOf(string) > -1) {
         alert("le HTLM contient le nom cherché");
         return true;
       }
        return false;
    }
}

puis tapez 
console.log(find(document.body, "evry"));

puis
console.log(find(document.body, "second"));

En action

Pourquoi ce code ne marche pas dans jsbin !

code

Trouver enfin un dernier bug !

Pourquoi ce code ne met pas en rouge l'item trouvé ?

function find(node, string) {
    if (node.nodeType == document.ELEMENT_NODE && node.nodeName !=
"SCRIPT") {
       for (var i = 0; i < node.childNodes.length; i++) {
          if (find(node.childNodes[i], string))
             return true;
          }
          return false;
    } else if (node.nodeType == document.TEXT_NODE) {
       if (node.nodeValue.indexOf(string) > -1) {
         //node.classList.add("find");
         node.style.color="red";
         return true;
       }
        return false;
    }
}

find(document.body, "second");

idée !

Parcours du DOM

Ecrire une fonction de parcours du DOM : printDomEle



HTML

<body>
article{article $}>section{section $}*2>p{para $}*3(puis Tab)
</body>


JS
fonctions utiles :   console.groupCollapsed(); console.groupEnd();
on utilise children pour avoir les enfants d'un noeud.
on utilise for of pour réaliser une boucle

printDomEle(document.body);




F12 : création de TD how to

Ouvrir le jsbin ci-dessous, lancer F12 et modifier la largeur du body
element.style {
// modifier la largeur du body
   width : 300px;


    JS Bin on jsbin.com

    Voici pour information, le code à mettre en place pour les tests.


    function isBodyWidthCorrect(expected) {
      var isCorrect = false;
      var width = Math.max(document.body.clientWidth,  document.body.getBoundingClientRect().width || 0);
      console.log(width);
      if (width==expected[0]) {
        isCorrect = true;
      } else{
        isCorrect = false;
      }
      // console.log("width: " + isCorrect);
      return isCorrect;
    }

    function createResultsDisplay() {
      var head = document.querySelector('head');
      var fontAwesome = document.createElement('link');
      fontAwesome.rel = 'stylesheet';
      fontAwesome.href = 'http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css';
      head.appendChild(fontAwesome);

      var gradeDisplayDiv = document.createElement('div');
      gradeDisplayDiv.classList.add('grade-display');
      gradeDisplayDiv.style.position = 'absolute';
      gradeDisplayDiv.style.minWidth = '200px';
      gradeDisplayDiv.style.backgroundColor = 'rgba(110, 120, 140, 0.8)';
      gradeDisplayDiv.style.left = '0px';
      gradeDisplayDiv.style.top = '0px';
      gradeDisplayDiv.style.padding = "0.5em";

      document.querySelector('body').appendChild(gradeDisplayDiv);
    }

    createResultsDisplay();

    var tests = [
      {
        test: isBodyWidthCorrect,
        params: [
          300
        ],
        desc: "Body width is set correctly."
      }
    ];

    var gradeLoop = setInterval(function() {
        var testObj,testCorrect;
        for (var i in tests) {
          //console.log(tests[0]);
            testCorrect = tests[i].test(tests[i].params);
            testObj = {
            desc: tests[i].desc,
            correct: testCorrect
          };
          /*
          updateResultsDisplay(testObj);
          if (arr.indexOf(arr[i]) === 0) {
            isCorrect = testCorrect;
          } else {
            isCorrect = isCorrect && testCorrect;
          }
          */
        }


        if (testCorrect) {
          clearInterval(gradeLoop);
            //displayCode(code);
            alert("Bravo!");
          updateResultsDisplay(testObj, function(){
          });
        }
      }, 1000);

    position d'un element :getBoundingClientRect()

    il est important de noter que :
     La position du coin en haut à gauche est relative à la zone de visualisation (viewport).

    Autrement dit si vous utilisez le scrool (et changez la zone de visualisation) les valeurs peuvent changer.

    ⍈ code

    La valeur retournée est un objet.

    Voici un exemple :

     [object DOMRect] {
      bottom: 3525.3125,
      height
    : 18,
      left
    : 8,
      right
    : 377,
      toJSON
    : function toJSON() { [native code] },
      top
    : 3507.3125,
      width
    : 369,
      x
    : 8,
      y
    : 3507.3125
    }

    Ainsi document.getElementById("id99").getBoundingClientRect().y; donne la position en y de l'élément id99.

    myClassList : Ecriture d'une API

    Nous allons écrire une classe JS simulant classList.

    JavaScript
    ptr = object.classList
    
    
    
    
    
    C'est un vrai exercice de programmation.

    Nous allons juste développer la méthode add et donnerons le reste du code à étudier.

    Nous savons récupérer les classes associées à un nœud du DOM.
    HTML<element class="p" ... >
    JavaScript
    Notons que le type retourné est "string"

    typeof(object.className)


    Mise en place de la fonction add

    Pour manipuler (ajouter, supprimer) un string, il est fréquent de transformer le string en tableau pour utiliser les méthodes efficaces sur les tableaux.

    1. transforme string en tableau
    2. ajoute la class au tableau
    3. transforme tableau en string

    Voici les fonctions de base

    var t = document.getElementById("f");
    var classTab,
        classString;
    console.log(" type of = " , typeof(t.className));

    // string->tab
    classTab = t.className.split(" ");
    console.log(classTab);

    //tab->string
    classString = classTab.join(" ");
    console.log(classString);


    JS Bin on jsbin.com

    Nous pouvons tester la présence d'une classe avant ajout

    JS Bin on jsbin.com

    Amélioration du code

    Cela marche, parfait, mais c'est maintenant que la partie intéressante commence !
    1. Créer des fonctions pour réutiliser notre code de base
    2. Introduire des éléments de test
    Création de fonctions de base

        var classesSeparator = " ";

        function splitClasses(classesString) {
            return classesString.split(classesSeparator);
        }

        function joinClasses(classes) {
            return classes.join(classesSeparator);
        }

        function indexInClasses(className, classes) {
            if (!className || !classes || !classes.length)
                return false;
            return classes.indexOf(className);
        }
    JS Bin on jsbin.com

    Amélioration du code

    Il est foncdemental d'imaginer que ce code va rentrer en conflit avec une autre bibliothèque JS. Imaginer que notre fonction add soit utilisée ainsi add(1,2) ?

    Les améliorations consistent


    1. Création d'un espace de noms
    2. Mise en évidence des fonctions internes
    3. Retour d'un objet pointant sur les fonctions

    Création d'un espace de nom

    Classes = (function () {
        //code
    })();

    Mise en évidence des fonctions et variables internes

    Nous marquons ces items avec un _

    exemple :
     var _classesSeparator = " ";


    Retour de l'objet

    La partie la plus subtile.

    Classes = (function () {
    ...
        return {
            "add": add
        };
    })();

    Le  principe reste simple. 

    Une fonction anonyme s'auto exécute et renvoie un objet que l'on affecte à Classes.
    Classes est un objet qui a un méthode add qui pointe en réalité sur la méthode add que nous avons définie et qui fait appelle à des fonctions internes qui ne sont plus atteignable : TOP !


    JS Bin on jsbin.com

    Pour finir, on peut evisager d'écrire l'ensemble des fonctions utiles.
      JS Bin on jsbin.com

    TP

    JSON : JavaScript Object Notation

    objet simple


    var personne = {
      "nom" : "dupont",  // noter les ""
      "prenom" : "denis" // pas de ,
    };

    console.log(personne.nom, personne.prenom);

    Objet imbriqué

    var personneAdresse = {
      "lieu" : "Paris",  // noter les ""
      "personne" : {
          "nom" : "dupont",  // noter les ""
          "prenom" : "denis" // pas de ,
      }
    };

    console.log(personneAdresse.personne.nom);

    Collection d'objets

    var personnesEntreprise = [
        {
            "lieu" : "Paris",
             "personne" : {
                  "nom" : "dupont",
                  "prenom" : "denis"
              }
        },
        {
            "lieu" : "Paris",
             "personne" : {
                  "nom" : "dupond",
                  "prenom" : "lolo"
              }
        },
    ];

    console.log(personnesEntreprise[0].personne.nom);


    var entreprise = {
      "nom" : "univ",
      "personnels" :
       [
            {
                "lieu" : "Paris",
                 "personne" : {
                      "nom" : "dupont",
                      "prenom" : "denis"
                  }
            },
            {
                "lieu" : "Paris",
                 "personne" : {
                      "nom" : "dupond",
                      "prenom" : "lolo"
                  }
            },
       ];
    };

    console.log(entreprise.personnels[0].personne.nom);

    Cas d'une bibliothèque 


    [
        {
            "title": "You Better Not Cry: Stories for Christmas",
            "author": "Burroughs, Augusten",
            "date": "2011-12-08T13:00:00.000Z",
            "asin": "B002U2DQAW",
        },
        {
            "title": "59 Seconds: Think a Little, Change a Lot",
            "author": "Wiseman, Richard",
            "date": "2011-11-26T13:00:00.000Z",
            "asin": "B002W8QXHW",
        },
        {
            "title": "Amusing Ourselves to Death",
            "author": "Postman, Neil",
            "date": "2011-11-13T13:00:00.000Z",
            "asin": "B0023ZLLH6",

        }
    ]

    JS + DOM + JSON

    Il est facile d'afficher les détails d'un livre dans une page. Les information sont stocké dans un objet JSON.


    JSON

    var myBook = {
            "title": "HTML5: Up & Running",
            "author": "Mark Pilgrim",
            "date": "2010-11-18T13:00:00.000Z",
            "asin": "0596806027",
            "thumbnail": "http://images.amazon.com/images/P/0596806027.01.ZTZZZZZZ.jpg",
            "infos": ["A humorous, informative, and well-written introduction to various parts of HTML5",  "the new semantic tags, multimedia, microdata, geolocation, offline storage, and more.",
             
            ],

    };


    Ces informations seront intégrées à la page par modification du DOM.

    DOM

    var p = document.createElement('p');
    p.innerHTML = "<strong> titre = "+ myBook.title + ' ' + myBook.author;
    p.innerHTML += '</br> description ' + myBook.infos.join(',');
    document.body.appendChild(p);

    https://jsbin.com/botave/edit?html,css,js,output

    JS + DOM + JSON

    MVC