Plan du module Programmation Web [avec JavaScript] ● Avant-propos ● Le noyau JavaScript ● JavaScript coté Client Web ● Divers Olivier Le Goaer [email protected] Avant-propos Quelques généralités sur JS ● Langage Ο Nécessite un interpréteur (versus. un compilateur) ● Langage Ο interprété (i.e. script) orienté objet Langage à "prototype" ● Confusion Ο fréquente avec Java Aucun lien entre ces 2 langages ! ● Anciennement Ο appelé ECMAScript Standardisé par ECMA (European Computer Manufacturers Association) Navigateurs et JavaScript ● Chaque navigateur est un interpréteur de JS Ο Course à la vitesse Ο Chrome (version 24 et >) est le vainqueur Mais peut être désactivé ! ● Permet un niveau d'interactivité plus riche qu'avec de l'HTML simple Ο Le document HTML/CSS chargé dans le navigateur peut être "remanié" dynamiquement Ο Certains traitements simples n’ont pas besoin d’être effectués par le serveur (comme le contrôle de saisies de l’utilisateur). Ces traitements peuvent être fait au niveau du navigateur. JS avec Notepad++ Aspects lexicaux Le noyau JavaScript ● Chaque Ο instruction est séparée par un ; Mais pas obligatoire. Le retour à la ligne suffit. ● Commentaires Ο Par ligne : // Ceci est un commentaire Ο Par bloc : /* Ceci est un commentaire */ ● Déclaration Ο ● Ο var annee, prix_ttc; Typage dynamique ● Implicite et peut changer en cours d'exécution... Types primitifs ● Entier Ο var annee = 2014; de caractère Ο var message="Gangnam style"; Ο var message='Gangnam style'; ● Booléen Ο Ο if (expr) { ... } else { ... } ● Boucle var prix_ttc = 45.789; //il s'agit d'un point, pas d'une virgule ● Chaîne Structures de contrôles ● Condition ● Réel Ο et typage Déclaration avec le mot clé var var estSympa=true; estGratuit=false; Ο while (expr) { ... } Ο do { ... } while (expr); ● Iteration Ο for (expr1; expr2; expr3) { ... } Ο for each (key in object) { ... } Ο for (value in object) { ... } Spécifiques aux Objets Opérateurs arithmétiques ● Opérateurs binaires ● Opérateurs Symbole Fonction Champs d'application + addition entiers ou réels + concaténation chaînes de caractères - soustraction entiers ou réels * multiplication entiers ou réels / division réelle (jamais entière) % reste de la division entière ● Opérateurs Opérateurs logiques Fonction && ET logique || OU logique Symbole Fonction > supérieur entiers ou réels >= Supérieur ou égal entiers < inférieur <= Inférieur ou égal == égal unaires Symbole Fonction Champs d'application + plus entiers ou réels - moins entiers ou réels ++ pré- ou post-incrémentation entiers ou réels -- pré- ou post-décrémentation entiers ou réels déclaration se fait à l'aide du mot clé function Ο function name(param1, param2) { ...; return value; } Ο Peut retourner une valeur (return) ou non ● L'appel ● Opérateurs se fait de manière classique Liaison des paramètres effectifs avec les paramètres formels, si il y en a. ● Le noyau JavaScript possède déjà une bibliothèque de fonctions prédéfinies Ο eval(), isNaN(), parseInt(), encodeURI(), ... Fonction === identique ! NON logique != différent !== non identique Portée et vie des variables ● Variables Ο function getLocalTVA(country) { var tva; //variable locale à la fonction. Vaut undefined à cet instant if (country == 'FR') { tva = 19.6; } else if (country == 'EN') { tva = 20.0; } return tva; } applyFrenchTax(); //appel de la fonction globale Une variable déclarée en dehors de toute fonction est accessible en tout point du script et de la page ● Cycle de vie d'une variable Ο Une variable locale est supprimée lorsque la fonction se termine Ο Une variale globale est supprimée à la fermeture de la page Fonction par expression ● JavaScript //variable globale function applyFrenchTax() { price = price * (1 + getLocalTVA('FR') / 100.0); } locale Une variable déclarée à l'interieur d'une fonction est seulement accessible dans cette fonction ● Variable Exemple illustratif var price = 12.56; unaires Symbole Ο Ο ● Opérateurs relationnels Symbole Fonction par déclaration ● La binaires //appel de la fonction // et agit sur la variable globale permet d'assigner des (pointeurs sur) fonctions à des variables Ο Fonctions anonymes dont l'appel se fait au travers des variables qui les référencent var messageBox = function () { alert("Justin Bieber"); } var messageBox2 = messageBox; var helloWorld = function (people) { alert("Hello " + people + "!"); } messageBox = function () { alert("Nothing here"); }; (function (msg) { alert(msg); })("Olivier Le Goaer"); messageBox2(); helloWorld("Olivier Le Goaer"); //Fonction anonyme auto-appelée //Quel est le résultat de cet appel ? //Quel est le résultat de cet appel ? Traitements des erreurs ● Exceptions Ο Programmation Objet ● Orientation Encadrer les portions de code susceptibles de poser problème et traiter l'erreur le cas échéant. ● Bloc try/catch Ο ● Paradigme try { //Run some code here } catch(err) { //Handle errors here } Un objet est décrit par ses propriétés et ses méthodes Ο Accès aux propriétés et méthodes par un point '.' Ο Auto-référence avec this Ο Visibilité des propriétés et méthodes : publics/privés Ο Ο ● Création var estSympa = new Boolean(true); var annee = new Number(2014); ● Array Ο Ο alert(p1.toString()); //affichera 'John a 50 ans' ● Utilisation var saveurs_yop = new Array[2]; saveurs_yop[0] = "banane"; saveurs_yop[1]="kiwi"; var message = new String("Gangnam style"); var p1 = new Person("John", 50); alert(p1.toString()); //affichera 'John a 50 ans' De la classe au prototype ● A défaut de classe... Ο Duplication des méthodes entre objets semblables ! Ο Il faudrait un mécanisme pour partager les méthodes ● ● ...on d'un constructeur d'objet function Person(_firstname, _age) { this.firstname = _firstname; //this => public, private sinon this.age = _age; this.toString = function() { return (this.firstname+' a '+this.age+' ans'); } } ● String Ο directe d'objet var p1=new Object(); p1.firstname="John"; p1.age=50; p1.toString = function() { return (this.firstname+' a '+this.age+' ans'); } ● Number (entiers et réels) Ο du concept de classe On ne peut pas définir de classes d'objets 2 façons de créer ses objets typeof(nom_variable) permet de connaître le type de la variable ● Boolean objet Ο ● Absence Objets primitifs objet Beaucoup de chose dans le langage est considéré comme objet (dont les fonctions !) Prototype : exemple function Child(_firstname, _age) { this.firstname = _firstname; //this => public, private sinon this.age = _age; Peu performant : empreinte mémoire accrue this.pleurer = function() { Alert('Je pleure'); } this.manger = function() { Alert('Je mange'); } utilise un "prototype" Ο Propriété des objets de type Function } Ο Le contenu d'un prototype (i.e. d'autres fonctions) peut être réutilisé par les fonctions entre elles Child.prototype = new Person(); //ou = Object.create(Person.prototype) ● ● L'héritage devient possible Redéfinition et surcharge de méthode supportées var c1 = new Child("Justin", 3); alert(c1.toString()); //accède à un méthode du prototype de Person (héritage !) c1.pleurer(); //accède à un méthode du prototype de Child delete c1; //destruction de l'objet Fermeture lexicale (closure) ● Fonction Ο const _rate = _tva / 100.0; function apply(_price) { return _price * (1 + _rate); } return apply; // retourne une référence sur la fonction apply Brise le principe de portée habituel Déjà vu avec la fonction constructeur d'un objet ;-) ● Les fonctions méthodes ont accès aux variables this.* ● La fonction externe renvoie une référence sur la fonction interne Ο function setTVA(_tva) { La fonction interne (inner) à accès au contexte de la fonction externe (outer) ● Ο définie au sein d'une autre fonction Closure : exemple de la TVA Autrement dit, la fonction renvoie une fonction en tenant compte d'un contexte préétablit } var TTCconso = setTVA(19.6); //TVA des produits de consommation var TTCculture = setTVA(7.7); //TVA des produits culturels //Me voilà avec 2 fonctions parfaitement intelligibles, // au lieu d'une seule fonction à 2 paramètres (la catégorie, le taux) var totalPanier = TTCconso(109.56) + TTCconso(25.0) + TTCculture(24.3); window.alert('Vous devez payer :' + totalPanier + ' euros'); Inclusion dans un document JavaScript coté Client Web ● Inclusion directe <html> <head> <script type="text/javascript"> //ici votre code JS </script> </head> <body>...<body> </html> ● Inclusion comme fichier externe <html> <head> <script type="text/javascript" src="./essai.js"></script> </head> <body>...<body> </html> Extension au noyau JS ● Classes Ο Window, Navigator, Screen, History, Location, ... ● Classes Ο d'objets BOM d'objets DOM DOM Document, DOM Elements, DOM Attributes, DOM Events, ... ● Classes Browser Object Model (BOM) ● Permet Ο de manipuler le navigateur Tous les navigateurs (IE, Firefox, Chrome, ...) sont des logiciels qui offrent les mêmes fonctionnalités de base ● Ouvrir/fermer des onglets, aller à une URL, mémoriser la liste des URL précédemment consultées, etc. ● Arborescence d'objets d'objets HTML Window Window Ο <a>, <area>, <base>, <button>, <form>, <iframe>, <image>, <input> (et ses variantes), <link>, <meta>, <object>, <option>, <select>, <style>, <table>, <td>, <th>, <tr>, <textarea> (fenêtre/onglet (fenêtre/ongletcourant) courant) location location document document DOM history history navigator navigator screen screen Chaque objet possède ses propriétés et méthodes Entrée/sortie BOM : exemple ● Méthodes d'interaction avec l'utilisateur par le biais de la fenêtre du navigateur ●2 méthodes d'entrée //Ferme l'onglet du navigateur window.close(); Ο var user_age = window.prompt ("Quel est votre age ?"); Ο var user_quit = window.confirm("Voulez vous quitter cette page ?"); ●1 méthode de sortie Ο Exercice : Quels sont les objets ? Quelles sont les propriétés ? ● Quelles sont les méthodes ? ● ● //redirige le navigateur vers une adresse window.location = "http://www.univ-pau.fr"; Objet instance de la classe Window Ο //récupère le nom de code du navigateur utilisé var monNavigateur = navigator.appCodeName; //Fais revenir une page en arrière (similaire au boutton 'Back') window.history.back(); //Affiche dans une boite de dialogue la résolution de l'écran utilisé window.alert(window.screen.availWidth + "x" + window.screen.availHeight); //Ecrit quelquechose dans le corps du document window.document.write("<b>Bienvenue à l'université de Pau</b>"); window.alert("Bienvenue sur ce site !"); Document Object Model (DOM) Document XHTML : exemple ● Représentation d'un document xhtml sous sa forme 100% objet Ο Les balises sont des noeuds et leurs imbrications forment une arborescence Ο Cette structure d'arbre est ensuite facile à manipuler ● L'arbre DOM est chargé dans le navigateur Ο L'arbre est parcouru par le moteur de rendu du navigateur afin de produire l'affichage graphique Ο Chaque modification de cet arbre provoque le rafraîchissement de l'affichage graphique ● Moteur Gecko pour Firefox, moteur Trident pour IE, etc. <!DOCTYPE html> <html> <head> <title>Bienvenue</title> <script type="text/javascript" src="./essai.js"></script> </head> <body> <p id="intro"> Pour me contacter : <a href="mailto:[email protected]">cliquez ici</a> <ul> <li>Uniquement en semaine</li> </ul> </p> <h1>S'inscrire à la Newsletter</h1> <form> <input type="text" name="news_email"/> </form> </body> </html> Arbre du document XHTML Propriétés d'un noeud <html> <html></html> </html> <head> <head></head> </head> <title> <title> </title> </title> #text(9) #text(9) <body> <body> </body> </body> <p> <p> </p> </p> <script> <script></script> </script> #text(20) #text(20) <a></a> <a></a> #text(11) #text(11) <h1> <h1></h1> </h1> <ul> <ul> </ul> </ul> <li></li> <li></li> #text(21) #text(21) #text(26) #text(26) <form> <form></form> </form> <input/> <input/> Popriétés Commentaires childNodes nœuds enfants firstChild premier nœud enfant lastChild dernier nœud enfant nextSibling prochain nœud d'un type (nœud de même niveau) parentNode nœud parent previousSibling nœud précédent d'un type (nœud de même niveau) nodeName nom du nœud nodeValue valeur / contenu du nœud nodeType type du nœud Selon la classe de l'objet HTML, des propriétés et méthodes spécifiques sont disponibles Navigation dans l'arbre Méthodes d'un noeud parentNode <html> <html></html> </html> firstChild Méthodes Commentaires createElement() Méthode pour créer un nouvel élément HTML dans le document (div, p, span, a, form, input, etc…). createTextNode() Méthode pour créer un nœud texte. appendChild() Pour ajouter l'élément créé dans le document. L'élément sera ajouté comme étant le dernier nœud enfant d'un élément parent. insertBefore() Pour ajouter l'élément créé avant un autre nœud. removeChild() Pour supprimer un nœud. lastChild <head> <head></head> </head> <body> <body></body> </body> nextSibling childNodes <p> <p></p> </p> <h1> <h1></h1> </h1> <form> <form></form> </form> Accès direct aux éléments ● Par la valeur de l'attribut id (si il existe) Ο var result = document.getElementById("intro") ; Ο Renverra 0 ou 1 résultat ● Par le nom de balise (Tag en anglais) Ο var result = document.getElementsByTagName("input") ; Ο Renverra 0 ou n résultats ● Par la valeur de l'attribut name (si il existe) Ο var result = document.getElementsByName("news_email") ; Ο Renverra 0 ou n résultats Evènements HTML Évènement Élément(s) concerné(s) load Document, FRAMESET, OBJECT unload BODY et FRAMESET error OBJECT, BODY et FRAMESET. abort BODY et FRAMESET select INPUT et TEXTAREA change INPUT, SELECT et TEXTAREA submit FORM reset FORM focus LABEL, INPUT, SELECT, TEXTAREA et BUTTON blur LABEL, INPUT, SELECT, TEXTAREA et BUTTON. resize Document scroll Document Accès : exemple de code <html> <head> <title>Bienvenue</title> <script type="text/javascript"> window.onload = function(e) { var htmltag = document.childNodes[0]; var bodyTag = htmltag.lastChild; var pTag = bodyTag.firstChild; pTag.style.color="#0000FF"; } </script> </head> <body><p>Lorem Ipsum</p></body> </html> Accès par navigation dans l'arbre <html> <head> <title>Bienvenue</title> <script type="text/javascript"> window.onload = function(e) { var pTag = document.getElementById('foo'); pTag.style.color="#0000FF"; } </script> </head> <body><p id="foo">Lorem Ipsum</p></body> </html> Accès direct Exemple de code Auto-référence avec this <!DOCTYPE html> <html> <head> <title>Bienvenue</title> <script type="text/javascript"> function addItem(e) { var item = document.createElement("li"); item.innerHTML="Lorem Ipsum"; e.appendChild(item); //greffe du noeud → rafraichissement de l'affichage } </script> </head> <body> <p id="intro"> Pour me contacter : <a href="mailto:[email protected]">cliquez ici</a> <ul onmouseover="addItem(this)"> <li>Uniquement en semaine</li> </ul> </p> </body> </html> Debuggers JavaScript ● Directement Divers Firebug (extension pour Firefox) Ο Editeur & console JS intégrés à Chrome Ο Console JS intégrée à IE et Opera ● Dans Ο un environnement de développement Javascript Debug Toolkit : plugin pour Eclipse ● Pour débugger sur Internet Explorer, Firefox, Safari, Chrome et Opera Editeur JS dans Chrome Editeur JS dans Chrome Triple validation des saisies La technologie Ajax 1) Contrôles natifs HTML5 du navigateur ● Asynchronous 1) Mais pas supportés par les navigateurs plus anciens :-/ Ο 2) Contrôles par du code JavaScript Ο dans un navigateur Ο Mais le JavaScript peut avoir été désactivé :-/ Un objet spécial peut effectuer des requêtes/réponses HTTP en arrière plan d'un document déjà chargé ● Bouscule 3) Contrôles par du code serveur (ex: PHP) 1) Solution 100% incontournable (mais alourdi la charge du serveur) Ο JavaScript and XML (Ajax) les habitudes de navigation par page Une seule URL (une seule page) semble désormais rendre toute les fonctionnalités possibles Requête HTTP Réponse HTTP Serveur ServeurWeb Web Requêtes HTTP <input type=''text'' pattern=''[0-9]{5}''/> + function isValidPostalCode(val) {...} function isValidPostalCode($val) {...} Réponses HTTP + intégration au DOM courant Serveur ServeurWeb Web Frameworks JavaScript UI jQuery Mobile Ext JS GWT Script.aculo.us DOM jQuery Dojo MooTools Angular Prototype ? 2D/3D