Maison >interface Web >js tutoriel >Script plus intelligent: de qualité javascript à partir de zéro
ou il peut avoir eu du code directement à l'intérieur:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Ne vous inquiétez pas encore des différences entre ces extraits. Il existe plusieurs façons - bonnes et mauvaises - dans lesquelles nous pouvons ajouter JavaScript à une page Web. Nous examinerons ces approches en détail plus loin dans ce chapitre.
JavaScript a été développé par Netscape et implémenté dans Netscape 2, bien qu'il ait été initialement appelé Livescript. La popularité croissante d'une autre langue, Java, a incité Netscape à changer le nom dans le but de profiter de la connexion, car JavaScript a fourni la possibilité de communiquer entre le navigateur et une applet Java.
Mais comme la langue a été développée à la fois par Netscape, dans sa forme originale, et par Microsoft, dans l'implémentation de JScript similaire mais différente, il est devenu clair que les scripts Web étaient trop importants pour être laissés aux loups de la concurrence des vendeurs. Ainsi, en 1996, le développement a été remis à un organisme international de normes appelé ECMA, et JavaScript est devenu ECMAScript ou ECMA-262.
La plupart des gens l'appellent encore JavaScript, et cela peut être une cause de confusion: en dehors du nom et des similitudes en syntaxe, Java et JavaScript ne sont rien de ressemblage.
JavaScript est le plus souvent utilisé comme langue côté client, et dans ce cas, le «client» fait référence au navigateur Web de l'utilisateur final, dans lequel JavaScript est interprété et exécuté. Cela le distingue des langages côté serveur comme PHP et ASP, qui s'exécutent sur le serveur et envoient des données statiques au client.
Étant donné que JavaScript n'a pas accès à l'environnement du serveur, il existe de nombreuses tâches qui, bien que triviale lorsqu'elles sont exécutées en PHP, ne peuvent tout simplement pas être réalisées avec JavaScript: la lecture et l'écriture dans une base de données, par exemple, ou la création de fichiers texte. Mais comme JavaScript a accès à l'environnement client, il peut prendre des décisions basées sur des données que les langages côté serveur n'ont tout simplement pas, comme la position de la souris, ou la taille rendue d'un élément.
qu'en est-il d'ActiveX?
Si vous êtes déjà très familier avec JScript de Microsoft, vous pensez peut-être "mais JavaScript peut faire certaines de ces choses en utilisant ActiveX", et c'est vrai - mais ActiveX ne fait pas partie d'ECMascript. ActiveX est un mécanisme spécifique à Windows pour permettre à Internet Explorer d'accéder à COM (le modèle d'objet composant au cœur de la technologie de script Windows) et s'exécute généralement uniquement dans des environnements de confiance, comme un intranet. Il existe des exceptions spécifiques que nous allons rencontrer - des exemples de contrôles ActiveX qui s'exécutent sans sécurité spéciale dans IE (comme le plugin flash et XMLHTTPRequest) - mais pour la plupart, les scripts utilisant ActiveX sont en dehors de la portée de ce livre.
Habituellement, l'ordinateur sur lequel un client est exécuté ne sera pas aussi puissant qu'un serveur, donc JavaScript n'est pas le meilleur outil pour effectuer de grandes quantités de traitement des données. Mais l'immédiateté du traitement des données sur le client rend cette option attrayante pour de petites quantités de traitement, car une réponse peut être reçue immédiatement; La validation du formulaire, par exemple, fait un bon candidat pour le traitement côté client.
mais pour comparer les langages côté serveur et côté client avec une vue à laquelle est «mieux» est erroné. Ni l'un ni l'autre n'est mieux - ce sont des outils pour différents travaux, et le croisement fonctionnel entre eux est petit. Cependant, des interactions accrues entre les scripts côté client et le côté serveur donnent naissance à une nouvelle génération de scripts Web, qui utilise des technologies telles que XMLHTTPRequest pour faire des demandes de données de serveur, exécuter les scripts côté serveur, puis gérer les résultats du côté client. Nous examinerons ces technologies en profondeur dans le chapitre 18, créant des applications Web avec JavaScript.
Restrictions de sécurité
Comme JavaScript fonctionne dans le domaine des données et programmes très sensibles, ses capacités ont été limitées pour garantir qu'il ne peut pas être utilisé avec malveillance. En tant que tels, il y a beaucoup de choses que JavaScript n'est tout simplement pas autorisée à faire. Par exemple, il ne peut pas lire la plupart des paramètres système à partir de votre ordinateur, interagir directement avec votre matériel ou provoquer l'exécution des programmes.
De plus, certaines interactions spécifiques qui seraient normalement autorisées pour un élément particulier ne sont pas autorisées dans JavaScript, en raison des propriétés de cet élément. Par exemple, modifier la valeur d'un formulaire
n'est généralement pas un problème, mais s'il s'agit d'un champ de saisie de fichiers (par exemple,
Il existe de nombreux exemples de restrictions de sécurité similaires, que nous allons développer à mesure qu'ils surviennent dans les applications que nous couvrirons dans ce livre. Mais pour résumer, voici une liste des principales limites et restrictions de sécurité de JavaScript, y compris celles que nous avons déjà vues. JavaScript ne peut pas:
En fin de compte, JavaScript pourrait ne pas être pris en charge du tout.
Il vaut également la peine de garder à l'esprit que de nombreux navigateurs incluent des options qui permettent une plus grande précision que d'activer ou de désactiver JavaScript. Par exemple, Opera comprend des options pour interdire les scripts de la fermeture de Windows, en déplaçant les fenêtres, en écrivant à la barre d'état, en recevant des clics avec le bouton droit… La liste continue. Il n'y a pas grand-chose à faire pour contourner cela, mais surtout, vous n'aurez pas besoin de? De telles options ont évolué pour supprimer les scripts «ennuyeux» (défilements de barres de statut, scripts sans clic, etc.) donc si vous restez à l'écart de ces types de scripts, le problème n'arrivera que rarement.
Les meilleures pratiques JavaScript mettent fortement l'accent sur la question de ce que vous devez faire pour les personnes dont les navigateurs ne prennent pas en charge les scripts, qui ont des scripts désactivés, ou qui ne sont pas en mesure d'interagir avec le script pour une autre raison (par exemple, l'utilisateur utilise une technologie d'assistance qui ne prend pas en charge les scripts).
Ce problème final est le plus difficile à résoudre, et nous nous concentrerons sur les solutions à ce problème dans le chapitre 16, JavaScript et l'accessibilité. Dans cette section, je voudrais examiner trois principes fondamentaux du bon javascript:
Le premier principe garantit que nous pensons à la situation dans son ensemble chaque fois que nous utilisons un script sur notre site. Le deuxième point permet une maintenance plus facile de notre côté, et une meilleure convivialité et Dégradation gracieuse pour l'utilisateur. (La dégradation gracieuse signifie que si JavaScript n'est pas pris en charge, le navigateur peut naturellement se rabattre ou «dégrader» en fonctionnalité non scriptée.) Le troisième principe rend le code plus facile à lire et à maintenir.
Il y a plusieurs raisons pour lesquelles les utilisateurs peuvent ne pas avoir JavaScript:
Le premier point couvre une gamme d'appareils étonnamment grande et en constante augmentation, y compris des appareils à petit écran comme les PDA, des appareils à l'écran à l'écran, y compris WebTV et le Sony PSP, ainsi que des navigateurs javascript hérités tels que Opera 5 et NetScape 4.
Le dernier point de la liste ci-dessus est sans doute le moins probable (à part les autres développeurs jouant l'avocat du diable!), Mais les raisons ne sont pas si importantes: certains utilisateurs n'ont tout simplement pas JavaScript, et nous devons les accueillir. Il n'y a aucun moyen de quantifier les nombres d'utilisateurs qui entrent dans cette catégorie, car la détection du support JavaScript du serveur est notoirement peu fiable, mais les chiffres que j'ai vus ont mis la proportion d'utilisateurs qui ont des «utilisateurs JavaScript entre 5% et 20%, selon que vous décrivez les robots de moteur de recherche comme des« utilisateurs ».
Solution
L'approche de longue date de ce problème consiste à utiliser l'élément HTML NOScript, dont le contenu est rendu par des navigateurs qui ne prennent pas du tout l'élément de script, et les navigateurs qui le prennent en charge mais qui ont des scripts désactivés.
Bien que ce soit une idée solide, dans la pratique, cette solution est devenue moins utile au fil du temps, car noscript ne peut pas se différencier par la capacité. Un navigateur qui offre une prise en charge JavaScript limitée ne sera pas en mesure d'exécuter un script compliqué, mais ces appareils sont des navigateurs capables de script, ils n'analyseront pas non plus l'élément noscript. Ces navigateurs se retrouveraient avec rien.
Une meilleure approche de ce problème consiste à commencer par le HTML statique, puis à utiliser des scripts pour modifier ou ajouter des comportements dynamiques dans ce contenu statique.
Regardons un exemple simple. La technique préférée pour fabriquer des menus DHTML utilise une liste non ordonnée comme structure du menu principal. Nous consacrerons l'ensemble du chapitre 15, des menus DHTML et de la navigation à ce sujet, mais ce court exemple illustre le point:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
La liste des liens est un HTML ordinaire, il existe donc pour tous les utilisateurs, qu'ils aient ou non les scripts activés. Si le script est pris en charge, notre script menu.js peut appliquer des comportements dynamiques, mais si le script n'est pas pris en charge, le contenu apparaît toujours. Nous n'avons pas différencié explicitement les appareils - nous venons de fournir du contenu dynamique si le navigateur peut le gérer, et statique sinon
L'approche «traditionnelle» de ce scénario serait de générer un menu dynamique séparé en JavaScript pur, et d'avoir du contenu statique de secours dans un élément noscript:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Mais, comme nous l'avons déjà vu, un large éventail d'appareils tombera dans ce filet, car le support JavaScript n'est plus une proposition tout ou rien. L'approche ci-dessus fournit du contenu par défaut à tous les appareils et applique les fonctionnalités scriptées uniquement si elle fonctionne.
Cette approche de script est populairement appelée Amélioration progressive , et c'est une méthodologie que nous utiliserons tout au long de ce livre.
Ne demandez pas!
Ni cette technique ni l'élément noscript ne doivent être utilisés pour ajouter un message qui se lit comme suit: "Veuillez activer JavaScript pour continuer." Au mieux, un tel message est présomptueux («Pourquoi devrais-je?»); Au pire, cela peut être inutile ("Je ne peux pas!") ou dénué de sens ("Qu'est-ce que JavaScript?"). Tout comme ces pages d'éclaboussures qui disent: «Veuillez mettre à niveau votre navigateur», ces messages sont aussi utiles à l'utilisateur Web moyen qu'un panneau routier qui se lit comme suit: «Veuillez utiliser une voiture différente».
Parfois, vous pouvez être confronté à une situation dans laquelle la fonctionnalité équivalente ne peut tout simplement pas être fournie sans JavaScript. Dans de tels cas, je pense qu'il est normal d'avoir un message statique qui informe l'utilisateur de cette incompatibilité (en termes non techniques, bien sûr). Mais, pour la plupart, essayez d'éviter de fournir ce type de message à moins que ce soit littéralement le seul moyen.
séparer le contenu du comportement signifie garder les différents aspects de la construction d'une page Web. Jeffrey Zeldman appelle cela comme le «tabouret à trois pattes» du développement Web (Zeldman, J. Designing with web standards. New Riders, 2003) - comprenant du contenu (HTML), la présentation (CSS) et le comportement (javascript) - qui ne mettent pas l'accent sur la différence.
Une bonne séparation rend les sites plus faciles à entretenir, plus accessibles et se dégrader bien dans les navigateurs plus anciens ou inférieurs.
Solution
À un extrême, qui est directement opposé à l'idéal de séparer le contenu du comportement, nous pouvons écrire du code en ligne directement à l'intérieur des gestionnaires d'événements d'attribut. Ceci est très désordonné et doit généralement être évité:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>Nous pouvons améliorer la situation en prenant le code qui fait le travail et en l'abstraire en fonction:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>Définir une fonction pour faire le travail pour nous, nous permet de fournir la majeure partie de notre code dans un fichier JavaScript séparé:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Mais une bien meilleure approche consiste à éviter d'utiliser complètement les gestionnaires d'événements en ligne. Au lieu de cela, nous pouvons utiliser le modèle d'objet de document (DOM) pour lier les gestionnaires d'événements aux éléments du document HTML. Le DOM est une interface de programmation standard par laquelle des langages comme JavaScript peuvent accéder au contenu des documents HTML, supprimant la nécessité pour que tout code JavaScript apparaisse dans le document HTML lui-même. Dans cet exemple, notre code HTML ressemblerait à ce qui suit:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Voici les scripts que nous utiliserions:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Cette approche nous permet d'ajouter, de supprimer ou de modifier les gestionnaires d'événements sans avoir à modifier le HTML, et comme le document lui-même ne s'appuie pas ou ne se référait pas du tout aux scripts, les navigateurs qui ne comprennent pas JavaScript ne seront pas affectés par celui-ci. Cette solution offre également les avantages de la réutilisabilité, car nous pouvons lier les mêmes fonctions à d'autres éléments que nécessaire, sans avoir à modifier le HTML.
Cette solution dépend de notre capacité à accéder aux éléments via le DOM, que nous couvrirons en profondeur au chapitre 5, en naviguant sur le modèle d'objet de document.
Les avantages de la séparation
En pratiquant une bonne séparation du contenu et du comportement, nous gagnons non seulement un avantage pratique en termes de dégradation plus fluide, mais aussi de l'avantage de la pensée en termes de séparation. Depuis que nous avons séparé le HTML et le JavaScript, au lieu de les combiner, lorsque nous regardons le HTML, nous sommes moins susceptibles d'oublier que sa fonction principale devrait être de décrire le contenu de la page, indépendamment de tout script.
Andy Clarke fait référence à la bagatelle des normes Web, qui est une analogie utile, une bagatelle ressemble à un bon site Web: lorsque vous regardez le bol, vous pouvez voir toutes les couches distinctes qui composent le dessert. L'opposé de cela pourrait être un gâteau aux fruits: lorsque vous regardez le gâteau, vous ne pouvez pas dire quel est chaque ingrédient différent. Tout ce que vous pouvez voir est une masse de gâteau.
Discussion
Il est important de noter que lorsque vous liez un gestionnaire d'événements à un élément comme celui-ci, vous ne pouvez pas le faire jusqu'à ce que l'élément existe réellement. Si vous mettez le script précédent dans la section tête d'une page telle qu'elle est, il rapporterait les erreurs et ne fonctionne pas, car le contenu Div n'a pas été rendu au point où le script est traité.
La solution la plus directe consiste à mettre le code dans un gestionnaire d'événements de charge. Il sera toujours en sécurité là-bas parce que l'événement de charge ne se déclenche qu'après que le document ait été entièrement rendu:
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">
ou plus clairement, avec un peu plus de frappe:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Le problème avec le gestionnaire d'événements de charge est qu'un seul script sur une page peut l'utiliser; Si deux scripts ou plus tentent d'installer des gestionnaires d'événements de chargement, chaque script remplacera le gestionnaire de celui qui l'a précédé. La solution à ce problème est de répondre à l'événement de chargement de manière plus moderne; Nous examinerons cela sous peu, dans la section intitulée «Faire fonctionner plusieurs scripts sur la même page».
Dans de nombreuses opérations JavaScript, les accolades et les demi-finales sont facultatifs, il y a donc une valeur à les inclure lorsqu'ils ne sont pas essentiels?
Solution
Bien que les accolades et les demi-colons soient souvent facultatifs, vous devez toujours les inclure. Cela rend le code plus facile à lire - par d'autres et par vous-même à l'avenir - et vous aide à éviter les problèmes lorsque vous réutilisez et réorganisez le code dans vos scripts (qui rendra souvent un semi-colon facultatif essentiel).
Par exemple, ce code est parfaitement valide:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Ce code est valide grâce à un processus dans l'interpréteur JavaScript appelé insertion de semi-colon. Chaque fois que l'interprète trouve deux fragments de code qui sont séparés par une ou plusieurs ruptures de ligne, et ces fragments n'auraient pas de sens s'ils étaient sur une seule ligne, l'interprète les traite comme si un point-virgule existait entre eux. Par un mécanisme similaire, les accolades qui entourent normalement le code à exécuter dans des instructions IF-Else peuvent être déduites de la syntaxe, même si elles ne sont pas présentes. Considérez ce processus comme l'interprète ajoutant les éléments de code manquants pour vous.
Même si ces éléments de code ne sont pas toujours nécessaires, il est plus facile de se rappeler de les utiliser lorsqu'ils sont nécessaires, et plus facile de lire le code résultant, si vous les utilisez de manière cohérente.
Notre exemple ci-dessus serait mieux écrit comme ceci:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Cette version représente l'ultime dans la lisibilité du code:
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">
Utilisation des littéraux de fonction
Au fur et à mesure que vous devenez expérimenté avec les subtilités de la langue JavaScript, il deviendra courant pour vous d'utiliser des littéraux de fonctions pour créer des fonctions anonymes au besoin, et les attribuer aux variables JavaScript et aux propriétés d'objet. Dans ce contexte, la définition de la fonction doit être suivie d'un point-virgule, qui met fin à l'affectation variable:
var sdetsomething = function (message)
{
...
};
Avant qu'un script puisse commencer à faire des choses passionnantes, vous devez le charger dans une page Web. Il existe deux techniques pour ce faire, dont l'une est nettement meilleure que l'autre.
Solution
La première et la plus directe de technique consiste à écrire du code directement dans un élément de script, comme nous l'avons vu auparavant:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Le problème avec cette méthode est que dans les navigateurs hérités et en texte uniquement - ceux qui ne prennent pas du tout l'élément de script - le contenu peut être rendu comme texte littéral.
Une meilleure alternative, qui évite ce problème, est toujours de mettre le script dans un fichier javascript externe. Voici à quoi cela ressemble:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Cela charge un fichier javascript externe nommé what-is-javascript.js. Le fichier doit contenir le code que vous allez autrement mettre dans l'élément de script, comme ceci:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Lorsque vous utilisez cette méthode, les navigateurs qui ne comprennent pas l'élément de script l'ignoreront et ne rendront aucun contenu (puisque l'élément est vide), mais les navigateurs le comprendront le chargement et le traiteront le script. Cela aide à séparer les scripts et le contenu et est beaucoup plus facilement entretenu - vous pouvez utiliser le même script sur plusieurs pages sans avoir à maintenir des copies du code dans plusieurs documents.
Discussion
Vous pouvez remettre en question la recommandation de ne pas utiliser de code directement dans l'élément de script. «Pas de problème», pourriez-vous dire. "Je vais juste mettre des commentaires HTML autour de lui." Eh bien, je devrais être en désaccord avec cela: utiliser des commentaires HTML pour «cacher» le code est une très mauvaise habitude dans laquelle nous devons éviter de tomber.
Mettre des commentaires HTML autour du code
Un analyseur validant n'est pas tenu de lire les commentaires, encore moins pour les traiter. Le fait que JavaScript commenté fonctionne du tout est un anachronisme - un retour à une ancienne pratique obsolète qui fait une hypothèse sur le document qui pourrait ne pas être vrai: il suppose que la page est servie à un analyseur non validant.
Tous les exemples de ce livre sont fournis en HTML (par opposition à XHTML), donc cette hypothèse est raisonnable, mais si vous travaillez avec XHTML (correctement servie avec un type de mime d'application / XHTML XML), les commentaires de votre code peuvent être défaurés par un casser de validation de validation avant le fait que le document est traité par le scénario, dans le cas où le fait de ne pas avoir été traité. Dans le but d'assurer la compatibilité des transition (et les avantages associés à vos propres habitudes de codage autant qu'aux projets individuels), je vous recommande fortement d'éviter de mettre des commentaires autour du code de cette manière. Votre javascript doit toujours être logé dans des fichiers javascript externes.
L'attribut de langue
L'attribut de langue n'est plus nécessaire. À l'époque où Netscape 4 et ses contemporains étaient les navigateurs dominants, l'attribut de langue de <script> Tag avait le rôle de reniflement pour le support de niveau supérieur (par exemple, en spécifiant JavaScript1.3), et a eu un impact sur de petits aspects de la façon dont l'interprète de script fonctionnait. </script>
Mais spécifier une version de JavaScript est assez dénué de sens maintenant que JavaScript est ECMascript, et l'attribut de langue a été obsolète en faveur de l'attribut type. Cet attribut spécifie le type MIME de fichiers inclus, tels que les scripts et les feuilles de style, et est le seul que vous devez utiliser:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Techniquement, la valeur doit être du texte / ecmascript, mais Internet Explorer ne le comprend pas. Personnellement, je serais plus heureux si c'est le cas, simplement parce que JavaScript est (ironiquement) un mot que j'ai beaucoup de difficulté à taper - j'ai perdu le compte du nombre de fois où une défaillance de script s'est produite parce que j'avais tapé Type = "Text / Javsacript".
Lorsque plusieurs scripts ne fonctionnent pas ensemble, c'est presque toujours parce que les scripts veulent affecter les gestionnaires d'événements pour le même événement sur un élément donné. Étant donné que chaque élément ne peut avoir qu'un seul gestionnaire pour chaque événement, les scripts remplacent les gestionnaires d'événements des autres.
Solution
Le suspect habituel est le gestionnaire d'événements de charge de l'objet Window, car un seul script sur une page peut utiliser cet événement; Si deux scripts ou plus l'utilisent, le dernier remplacera ceux qui l'ont précédé.
Nous pourrions appeler plusieurs fonctions de l'intérieur d'un seul gestionnaire de chargement, comme ceci:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Mais, si nous avons utilisé ce code, nous serions liés à un seul code à partir duquel nous devions faire tout ce dont nous avions besoin au moment du chargement. Une meilleure solution fournirait un moyen d'ajouter des gestionnaires d'événements de charge qui n'enfluraient pas avec d'autres gestionnaires.
Lorsque la fonction unique suivante est appelée, elle nous permettra d'attribuer un certain nombre de gestionnaires d'événements de charge, sans aucun d'entre eux en conflit:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Une fois cette fonction en place, nous pouvons l'utiliser n'importe quel nombre de fois:
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">
vous avez l'idée!
Discussion
JavaScript inclut des méthodes pour ajouter (et supprimer) les auditeurs d'événements, qui fonctionnent un peu comme les gestionnaires d'événements, mais permettent à plusieurs auditeurs de s'abonner à un seul événement sur un élément. Malheureusement, la syntaxe des écouteurs d'événements est complètement différente dans Internet Explorer que dans d'autres navigateurs: où IE utilise une méthode propriétaire, d'autres implémentent la norme W3C. Nous rencontrerons fréquemment cette dichotomie, et nous en discuterons en détail dans le chapitre 13, Html dynamique de base
La méthode standard W3C est appelée ADDEVENTListener:
<div <br> onmouseover="changeBorder('red')" <br> onmouseout="changeBorder('black')">
La méthode IE est appelée attacheevent:
Example 1.1. separate-content-behaviors.js (excerpt) <br> <br> function changeBorder(element, to) <br> { <br> element.style.borderColor = to; <br> }
Comme vous pouvez le voir, la construction standard prend le nom de l'événement (sans le préfixe «ON»), suivi de la fonction qui doit être appelée lorsque l'événement se produit, et un argument qui contrôle l'événement bouillonnant (voir le chapitre 13, HTML dynamique de base pour plus de détails à ce sujet). La méthode IE prend le nom du gestionnaire d'événements (y compris le préfixe " on "), suivi du nom de la fonction.
pour les assembler, nous devons ajouter quelques tests pour vérifier l'existence de chaque méthode avant d'essayer de l'utiliser. Nous pouvons le faire en utilisant le type d'opérateur JavaScript, qui identifie différents types de données (comme "String", "Number", "Boolean", "Object", "Array", "Fonction" ou "Undefined"). Une méthode qui n'existe pas renverra "non défini".
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Il y a une complication supplémentaire: dans Opera, l'événement de charge qui peut déclencher plusieurs écouteurs d'événements provient de l'objet de document, pas la fenêtre. Mais nous ne pouvons pas simplement utiliser un document car cela ne fonctionne pas dans les navigateurs de Mozilla plus âgés (comme Netscape 6). Pour tracer un itinéraire à travers ces bizarreries, nous devons tester pour Window.AddeventListener, puis document.addeventListener, puis Window.Attachevent, dans cet ordre.
Enfin, pour les navigateurs qui ne prennent en charge aucune de ces méthodes (Mac IE 5, en pratique), la solution de secours consiste à enchaîner plusieurs gestionnaires d'événements à l'ancienne afin qu'ils soient appelés à leur tour lorsque l'événement se produit. Nous le faisons en construisant dynamiquement un nouveau gestionnaire d'événements qui appelle tout gestionnaire existant avant d'appeler le gestionnaire nouvellement attribué lorsque l'événement se produit. (Cette technique a été lancée par Simon Willison.)
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Ne vous inquiétez pas si vous ne comprenez pas les détails de la façon dont cela fonctionne - nous explorerons les techniques impliquées dans des détails beaucoup plus en détail dans le chapitre 13, HTML dynamique de base. Là, nous apprendrons que les auditeurs d'événements sont utiles non seulement pour l'événement de chargement, mais pour tout type de script axé sur les événements.
Si vous avez déjà créé quelque chose dont vous êtes fier, vous comprendrez le désir de protéger votre propriété intellectuelle. Mais JavaScript sur le Web est une langue open source par nature; Il vient au navigateur dans sa forme source, donc si le navigateur peut l'exécuter, une personne peut la lire.
Il existe quelques applications sur le Web qui prétendent offrir un cryptage à code source, mais en réalité, vous ne pouvez rien faire pour crypter le code source qu'un autre codeur ne pourrait pas décrypter en quelques secondes. En fait, certains de ces programmes causent réellement des problèmes: ils reformatent souvent le code de manière à le rendre plus lent, moins efficace ou tout simplement brisé. Mon conseil? Éloignez-vous d'eux comme la peste.
Mais quand même, le désir de cacher du code demeure. Il y a quelque chose que vous pouvez faire pour obscurcir, sinon crypter carrément, le code que vos utilisateurs peuvent voir.
Solution
Le code qui a été dépouillé de tous les commentaires et de l'espace blanc inutile est très difficile à lire, et comme vous pouvez vous y attendre, l'extraction de bits individuels de fonctionnalité de ce code est extrêmement difficile. La technique simple de compression de vos scripts de cette manière peut décourager tout sauf le pirate le plus déterminé. Par exemple, prenez ce code:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Nous pouvons compresser ce code dans les deux lignes suivantes simplement en supprimant les espaces blancs inutiles:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Cependant, rappelez-vous ce mot important - inutile. Certains espaces sont essentiels, comme les espaces uniques après Var et Typeof.
Discussion
Cette pratique présente des avantages en dehors des avantages de l'obscurcissement. Les scripts qui sont dépouillés des commentaires et des espaces blancs inutiles sont plus petits; Par conséquent, ils sont plus rapides et peuvent traiter plus rapidement.
Mais n'oubliez pas que le code doit rester strictement formaté à l'aide de terminateurs et de bretelles de ligne de semi-colon (comme nous l'avons discuté dans la section appelée «utilisant des accolades et des semi-colons (pratique cohérente)»); Sinon, la suppression des ruptures de ligne fera fonctionner les lignes de code et provoquera finalement des erreurs.
Avant de commencer la compression, n'oubliez pas de faire une copie du script. Je sais que cela semble évident, mais j'ai fait cette erreur de nombreuses fois, et c'est encore plus exaspérant pour être si élémentaire! Ce que je fais ces jours-ci, c'est écrire et maintenir des scripts sous leur forme entièrement espacée et commentée, puis les exécuter à travers un tas d'expressions de recherche / remplacement juste avant leur publication. Habituellement, je garde deux copies d'un script, nommé myscript.js et myscript-sold.js, ou quelque chose de similaire.
Nous reviendrons à ce sujet dans le chapitre 20, en maintenant le rythme, où nous en discuterons entre une gamme de techniques pour améliorer la vitesse et l'efficacité des scripts, ainsi que la réduction de la quantité d'espace physique dont ils ont besoin.
Le débogage est le processus de recherche et (espérons-le) de corriger les bogues. La plupart des navigateurs ont une sorte de rapport de bogues intégré, et quelques débogueurs externes méritent également d'être enquêtés.
Comprendre les rapports d'erreur intégrés d'un navigateur
L'opéra, les navigateurs de Mozilla (comme Firefox) et Internet Explorer ont tous des fonctionnalités décentes de rapports de bogues intégrées, mais l'opéra et les outils de débogage de Mozilla sont les plus utiles.
opéra
Ouvrez la console JavaScript à partir des outils> Advanced> Console JavaScript. Vous pouvez également le définir sur l'ouvrir automatiquement lorsqu'une erreur se produit en allant à des outils> Préférences> Avancé> Contenu, puis en cliquant sur le bouton des options JavaScript pour ouvrir sa boîte de dialogue et vérifier l'ouverture de la console JavaScript sur l'erreur.
Firefox et autres navigateurs Mozilla
Ouvrez la console JavaScript à partir des outils> Console JavaScript.
Explorateur Internet pour Windows
Allez dans les outils> Options Internet> Avancé et décochez l'option Désactiver le débogage du script, puis vérifiez l'option Afficher une notification sur chaque erreur de script, pour faire apparaître une boîte de dialogue chaque fois qu'une erreur se produit.
Explorateur Internet pour Mac
Accédez à Explorer> Préférences> Browser Web> Contenu Web et cochez l'option Afficher des alertes d'erreur de script.
Safari n'inclut pas les rapports de bogues par défaut, mais les versions récentes ont un menu de débogage «secret», y compris une console JavaScript, que vous pouvez activer en entrant la commande de terminal suivante. (Le $ représente l'invite de commande et ne doit pas être dactylographié.)
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Vous pouvez également utiliser une extension appelée Safari Enhancer, qui comprend une option pour vider les messages JavaScript sur la console Mac OS; Cependant, ces messages ne sont pas très utiles.
Comprendre les différents messages de la console des navigateurs peut prendre un peu de pratique, car chaque navigateur donne des informations si différentes. Voici un exemple d'erreur - un appel de fonction mal typé:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Firefox donne un rapport concis mais très précis, qui comprend le numéro de ligne auquel l'erreur s'est produite, et une description, comme le montre la figure 1.1, «La console des erreurs JavaScript dans Firefox».
Figure 1.1. La console des erreurs JavaScript dans Firefox
Comme l'illustre la figure 1.2, «la console JavaScript dans l'opéra», l'opéra donne un rapport extrêmement verbeux, y compris une rentrée à l'événement à partir de laquelle l'erreur est originaire, une notification de la ligne où elle s'est produite et une description.
Une backtrace aide lorsqu'une erreur se produit dans le code qui a été initialement appelé par un autre code; Par exemple, lorsqu'un manche d'événement appelle une fonction qui continue d'appeler une deuxième fonction, et c'est à ce stade que l'erreur se produit. La console de l'opéra retracera ce processus à travers chaque étape à son événement ou à son appel d'origine.
Internet Explorer donne le type de rapport assez basique illustré à la figure 1.3, «La console JavaScript dans Windows IE». Il fournit le numéro de la ligne à laquelle l'interprète a rencontré l'erreur (cela peut ou non être proche de la véritable emplacement du problème réel), plus un résumé du type d'erreur, bien qu'il n'explique pas les spécificités de l'erreur elle-même. (Internet Explorer est particulièrement mauvais pour localiser les erreurs dans les fichiers JavaScript externes. Souvent, le numéro de ligne qu'il rapportera comme l'emplacement d'erreur sera en fait le numéro de la ligne à laquelle le script est chargé dans le fichier HTML.)
Figure 1.2. La console JavaScript dans l'opéra
Figure 1.3. La console JavaScript dans Windows IE
Comme vous l'avez probablement rassemblé, je ne suis pas trop impressionné par les rapports d'erreur d'Internet Explorer, mais c'est bien mieux que rien: au moins vous savez qu'une erreur s'est produite.
en utilisant alerte
La fonction d'alerte est un moyen très utile d'analyser les erreurs - vous pouvez l'utiliser à tout moment d'un script pour sonder des objets et des variables pour voir s'ils contiennent les données que vous attendez. Par exemple, si vous avez une fonction qui a plusieurs branches conditionnelles, vous pouvez ajouter une alerte dans chaque condition pour savoir ce qui est exécuté:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
peut-être que la valeur des années ne revient pas en tant que nombre, comme elle le devrait. Vous pouvez ajouter au début de votre script une alerte qui teste la variable pour voir de quel type il s'agit:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
En théorie, vous pouvez mettre n'importe quelle quantité d'informations dans une boîte de dialogue d'alerte, bien qu'une très longue chaîne de données puisse créer une boîte de dialogue si large que certaines informations seraient coupées ou à l'extérieur de la fenêtre. Vous pouvez éviter cela en formatant la sortie avec des caractères d'échappement, tels que n pour une rupture de ligne.
en utilisant un coup de trypt
La construction de coups d'essai est un moyen incroyablement utile d'obtenir un script juste pour «essayer quelque chose», vous laissant gérer toutes les erreurs qui peuvent en résulter. La construction de base ressemble à ceci:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Si vous ne savez pas d'où provient une erreur, vous pouvez envelopper un tournant autour d'un très grand bloc de code pour piéger la défaillance générale, puis le serrer autour de morceaux de code progressivement plus petits dans ce bloc. Par exemple, vous pouvez envelopper une attelle d'essayer autour de la première moitié d'une fonction (à un point pratique du code), puis autour de la seconde moitié, pour voir où l'erreur se produit; Vous pouvez ensuite diviser à nouveau la moitié du suspect, à un point pratique, et continuer jusqu'à ce que vous ayez isolé la ligne problématique.
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">
Souvent, j'utilise un itérateur for-in pour parcourir l'objet entier et découvrir ce qu'il dit:
<div <br> onmouseover="changeBorder('red')" <br> onmouseout="changeBorder('black')">
Écriture sur la page ou la fenêtre
Si vous examinez de nombreuses données lors du débogage, ou si vous avez affaire à des données formatées de manière compliquée, il est souvent préférable d'écrire ces données directement sur une page ou une fenêtre contextuelle que d'essayer de faire face à de nombreuses boîtes de dialogue d'alerte. Si vous examinez des données dans une boucle, en particulier, vous pourriez finir par générer des centaines de dialogues, chacun dont vous devrez rejeter manuellement? Un processus très fastidieux.
Dans ce type de situations, nous pouvons utiliser la propriété InnerHTML d'un élément pour écrire les données sur la page. Voici un exemple dans lequel nous construisons une liste en utilisant le contenu d'un tableau (données), puis écrivons-les dans un test div:
Example 1.1. separate-content-behaviors.js (excerpt) <br> <br> function changeBorder(element, to) <br> { <br> element.style.borderColor = to; <br> }
Nous pouvons également écrire les données dans une fenêtre contextuelle, ce qui est utile s'il n'y a pas d'endroit pratique pour le mettre sur la page:
<div >
Vous pouvez formater la sortie comme vous le souhaitez, et les utiliser pour structurer les données de toutes les manières qui vous permettent de trouver plus facilement l'erreur.
Lorsque vous travaillez avec de plus petites quantités de données, vous pouvez obtenir un avantage similaire en écrivant les données sur l'élément de titre principal:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Cette approche finale est plus utile lors du suivi des données qui changent continuellement ou rapidement, comme une valeur traitée par une fonction SetInterval (une minuterie asynchrone que nous rencontrerons correctement dans le chapitre 14, temps et mouvement).
en utilisant un débogueur externe
Je peux recommander deux débogueurs:
Les débogueurs externes sont un moyen beaucoup plus détaillé d'analyser vos scripts et d'avoir des capacités beaucoup plus importantes que leurs homologues en cas de navigateur. Les débogueurs externes peuvent faire des choses comme arrêter l'exécution du script à des points spécifiques ou regarder des propriétés particulières afin que vous soyez informé de tout changement, mais il peut être causé. Ils incluent également des fonctionnalités qui vous permettent de «parcourir» le code par ligne, afin d'aider à trouver des erreurs qui ne peuvent se produire que brièvement, ou qui sont autrement difficiles à isoler.
Les débogueurs externes sont des logiciels complexes, et il peut prendre du temps aux développeurs pour apprendre à les utiliser correctement. Ils peuvent être très utiles pour mettre en évidence les erreurs logiques et précieuses en tant qu'outils d'apprentissage à part entière, mais ils sont limités dans leur capacité à aider avec les incompatibilités du navigateur: ils n'y sont utiles que si le bug que vous recherchez est dans le navigateur que le débogueur prend en charge!
Si vous ouvrez la console JavaScript dans Firefox, vous verrez qu'il comprend des options pour afficher les erreurs et les avertissements. Les avertissements vous informent du code que, bien qu'il ne soit pas erroné en soi, s'appuie sur le traitement automatique des erreurs, utilise une syntaxe obsolète ou est d'une autre manière intime à la spécification ECMAScript. (Pour voir ces avertissements, il peut être nécessaire de permettre des rapports stricts en tapant l'adresse sur: config and définir javascript.options.strict to true.)
Par exemple, le fruit variable est défini deux fois dans le code ci-dessous:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Nous aurions dû omettre le deuxième var, car VAR est utilisé pour déclarer une variable pour la première fois, ce que nous avons déjà fait. Figure 1.4, «La console JavaScript Avertures dans Firefox» montre comment la console JavaScript mettra en évidence notre erreur comme un avertissement.
Figure 1.4. La console des avertissements JavaScript dans Firefox
Il existe plusieurs faux pas de codage qui peuvent provoquer des avertissements comme celui-ci. Par exemple:
Par exemple, une condition de test comme if (document.getElementById) suppose l'existence de la méthode GetElementById, et les banques sur le fait que les capacités automatiques de gestion des erreurs de JavaScript convertiront une méthode inexistante en faux dans les navigateurs dans lesquels cette méthode n'existe pas. Pour atteindre la même fin sans voir un avertissement, nous serions plus précis, en utilisant if (typeof document.getElementByid! = 'Undefined').
Il existe également des avertissements liés à la fonction et une gamme d'autres avertissements divers qui incluent mon préféré, «Expression inutile», qui est produit par une déclaration dans une fonction qui ne fait rien:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Pour un aperçu complet du sujet, je recommande l'article d'Alex Vincent pour s'attaquer aux avertissements stricts JavaScript.
Les avertissements n'ont pas d'importance dans le sens où ils n'empêchent pas nos scripts de fonctionner, mais travailler pour éviter les avertissements nous aide à adopter une meilleure pratique de codage, ce qui crée finalement des avantages d'efficacité. Par exemple, les scripts fonctionnent plus vite à Mozilla s'il n'y a pas de stricts avertissements, un sujet que nous reviendrons dans le chapitre 20, en gardant le rythme.
Type Test de conversion
Bien que nous ne devons pas compter sur la conversion de type pour tester une valeur qui pourrait être indéfinie, il est parfaitement bien de le faire pour une valeur qui pourrait être nul, car la spécification ECMAScript nécessite que Null évalue à False. Ainsi, par exemple, après avoir déjà établi l'existence de GetElementByid en utilisant le type d'opérateur comme indiqué ci-dessus, il est parfaitement sûr à partir de là pour tester les éléments individuels comme indiqué ci-dessous, car GetElementByid renvoie NULL pour les éléments inexistants dans le DOM:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Dans ce chapitre, nous avons parlé des approches des meilleures pratiques pour les scripts qui rendront notre code plus facile à lire et à gérer, et lui permettra de dégrader gracieusement dans des appareils non pris en charge. Nous avons également commencé à présenter certaines des techniques dont nous aurons besoin pour créer des scripts utiles, y compris l'écouteur d'événements de chargement omniprésent que nous utiliserons pour presque toutes les solutions de ce livre!
Nous avons déjà couvert des choses assez avancées, alors ne vous inquiétez pas si une partie était difficile à prendre. Nous reviendrons sur tous les concepts et techniques que nous avons introduits ici à mesure que nous progressons dans les chapitres restants.
Les navigateurs donnent aux programmes JavaScript accès aux éléments d'une page Web via le modèle d'objet de document (DOM) - une représentation interne des en-têtes, paragraphes, listes, styles, identifiants, classes et toutes les autres données trouvées dans le HTML sur votre page.
Le DOM peut être considéré comme un arbre composé de nœuds interconnectés. Chaque balise d'un document HTML est représentée par un nœud; Toutes les balises imbriquées à l'intérieur de cette balise sont des nœuds qui y sont connectés en tant qu'enfants ou des branches de l'arbre. Chacun de ces nœuds est appelé nœud d'élément. (À proprement parler, chaque nœud d'élément représente une paire de balises - les balises de début et de fin d'un élément (par exemple,
et
) - ou un seul balise d'auto-fermage (par exemple,<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Le DOM de cette page pourrait être visualisé comme la figure 5.1, «la structure Dom d'une page HTML simple, visualisée comme une hiérarchie d'arbre».
Chaque page a un nœud de document, mais ses descendants sont dérivés du contenu du document lui-même. Grâce à l'utilisation des nœuds d'élément, des nœuds de texte et des nœuds d'attribut, chaque élément d'information sur une page est accessible via JavaScript.
Le DOM n'est pas seulement limité à HTML et JavaScript, cependant. Voici comment le site de spécification W3C DOM explique la question:
Le modèle d'objet de document est une interface neutre de la plate-forme et du langage qui permettra aux programmes et aux scripts d'accéder et de mettre à jour dynamiquement le contenu, la structure et le style des documents.
Ainsi, même si le mélange de JavaScript et de HTML est la combinaison la plus courante de technologies dans lesquelles le DOM est utilisé, les connaissances que vous acquérez de ce chapitre peuvent être appliquées à un certain nombre de langages de programmation et de types de documents différents.
Afin de faire de vous un «maître de votre domaine», ce chapitre expliquera comment trouver tout élément que vous recherchez sur une page Web, puis changez-le, réorganisez-le ou effacez-le complètement.
Figure 5.1. La structure DOM d'une page HTML simple, visualisée comme une hiérarchie d'arbre
L'accès fournit le contrôle, le contrôle est la puissance, et vous êtes un programmeur d'alimentation, non? Vous avez donc besoin d'accéder à tout ce qui se trouve sur une page Web. Heureusement, JavaScript vous donne accès à n'importe quel élément d'une page en utilisant seulement quelques méthodes et propriétés.
Solution
bien qu'il soit possible de naviguer dans un document HTML comme une feuille de route? À partir de la maison et de vous diriger vers votre nœud de destination à la fois? Il s'agit généralement d'un moyen inefficace de trouver un élément car il nécessite beaucoup de code, et tout changement dans la structure du document signifie généralement que vous devez réécrire vos scripts. Si vous voulez trouver quelque chose rapidement et facilement, la méthode que vous devez tatouer sur le dos de votre main est le document.
En supposant que vous avez le bon balisage en place, GetElementByid vous permettra immédiatement d'accéder à n'importe quel élément par sa valeur d'attribut d'ID unique. Par exemple, imaginez que votre page Web contient ce code:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>Vous pouvez utiliser l'attribut ID A Element pour obtenir un accès direct à l'élément lui-même:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>La valeur de la variable ElementRef sera désormais référencée à l'élément A - toutes les opérations que vous effectuez sur ElementRef affecteront cet hyperlien exact.
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>Comme on peut le voir à partir de son nom, GetElementsByTagname prend un nom de balise et renvoie tous les éléments de ce type. Supposons que nous avons ce code HTML:
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">Nous pouvons récupérer une collection qui contient chacun des hyperliens comme SO:
<div <br> onmouseover="changeBorder('red')" <br> onmouseout="changeBorder('black')">La valeur des ancres variables sera désormais une collection d'éléments. Les collections sont similaires aux tableaux en ce que chacun des éléments d'une collection est référencé à l'aide de la notation du support carré, et les éléments sont indexés à commencer numériquement à zéro. La collection renvoyée par GetElementsByTagName trie les éléments par leur commande source, afin que nous puissions référencer chacun des liens ainsi:
Example 1.1. separate-content-behaviors.js (excerpt) <br> <br> function changeBorder(element, to) <br> { <br> element.style.borderColor = to; <br> }En utilisant cette collection, vous pouvez itérer sur les éléments et effectuer une opération sur eux, comme l'attribution d'une classe en utilisant la propriété ClassName des nœuds d'élément:
<div >Contrairement à GetElementById, qui peut être appelé sur le nœud de document uniquement, la méthode GetElementsByTagName est disponible à partir de chaque nœud d'élément. Vous pouvez limiter la portée de la méthode GetElementsByTagname en l'exécutant sur un élément particulier. GetElementsByTagName ne renvoie que des éléments qui sont des descendants de l'élément sur lequel la méthode a été appelée.
Si nous avons deux listes, mais que nous voulons attribuer une nouvelle classe aux liens dans une seule liste, nous pouvons cibler ces éléments exclusivement en appelant GetElementsByTagname sur leur liste de parents:
Example 1.2. separate-content-behaviors.js <br> <br> function changeBorder(element, to) <br> { <br> element.style.borderColor = to; <br> } <br> <br> var contentDiv = document.getElementById('content'); <br> <br> contentDiv.onmouseover = function() <br> { <br> changeBorder('red'); <br> }; <br> <br> contentDiv.onmouseout = function() <br> { <br> changeBorder('black'); <br> };Pour cibler la liste des étoiles, nous devons obtenir une référence à l'élément Parent UL, puis appeler GetElementsByTagname directement:
window.onload = function() <br> { <br> var contentDiv = document.getElementById('content'); <br> <br> ... <br> };La valeur de la variable starsanchors sera une collection des éléments A à l'intérieur de la liste des étoiles non ordonnés, au lieu d'une collection de tous les éléments de la page.
DOM 0 Collections
De nombreux éléments «spéciaux» dans un document HTML sont accessibles par des moyens encore plus directs. L'élément corporel du document est accessible en tant que document.body. Une collection de toutes les formulaires dans un document peut être trouvée dans Document.Forms. Toutes les images d'un document peuvent être trouvées dans Document.images.
En fait, la plupart de ces collections existent depuis avant que le Dom ne soit standardisé par le W3C, et sont communément appelés propriétés DOM 0.
Étant donné que les implémentations initiales de ces fonctionnalités n'étaient pas standardisées, ces collections se sont parfois révélées peu fiables dans les navigateurs qui évoluent vers la conformité des normes. Les premières versions de certains navigateurs de Mozilla (par exemple, Firefox), par exemple, n'ont pas pris en charge ces collections sur des documents XHTML.
Les navigateurs d'aujourd'hui font généralement un bon travail pour soutenir ces collections; Cependant, si vous rencontrez des problèmes, cela vaut la peine d'essayer la méthode GetElementsByTagname plus verbeux pour accéder aux éléments pertinents. Au lieu de document.body, par exemple, vous pouvez utiliser:
var body = document.getElementsByTagName ("Body") [0];
Discussion
Si vous avez vraiment besoin de parcourir l'élément de hiérarchie DOM par élément, chaque nœud a plusieurs propriétés qui vous permettent d'accéder aux nœuds connexes:
Si l'une de ces propriétés n'existe pas pour un nœud spécifique (par exemple, le dernier nœud d'un parent n'aura pas un prochain frère), ils auront une valeur nul.
Jetez un œil à cette page simple:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
L'élément de liste avec ID Star2 pourrait être référencé à l'aide de l'une de ces expressions:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
nœuds d'espace blanc
Certains navigateurs créeront des nœuds d'espace blanc entre les nœuds d'élément dans n'importe quelle structure DOM qui a été interprétée à partir d'une chaîne de texte (par exemple, un fichier HTML). Les nœuds d'espace blanc sont des nœuds de texte qui ne contiennent que des espaces blancs (onglets, espaces, nouvelles lignes) pour aider à formater le code de la manière dont il a été écrit dans le fichier source.
Lorsque vous traversez le nœud Dom par nœud en utilisant les propriétés ci-dessus, vous devez toujours permettre ces nœuds d'espace blanc. Habituellement, cela signifie vérifier que le nœud que vous avez récupéré est un nœud d'élément, pas seulement un nœud d'espace blanc qui sépare les éléments.
Il existe deux façons faciles de vérifier si un nœud est un nœud d'élément ou un nœud de texte. La propriété Nodename d'un nœud de texte sera toujours «#text», tandis que le nom de noeud d'un nœud d'élément identifiera le type d'élément. Cependant, pour distinguer les nœuds de texte des nœuds d'élément, il est plus facile de vérifier la propriété NodeType. Les nœuds d'élément ont un
nodetype de 1, tandis que les nœuds de texte ont un nodype de 3. Vous pouvez utiliser ces connaissances comme test lors de la récupération des éléments: Exemple 5.9. Access_element4.js (extrait)
var star2 = document.getElementById ("Star1"). NextSibling;
while (star2.NodeType == "3")
{
star2 = star2.NextSibling;
}
En utilisant ces propriétés DOM, il est possible de commencer votre voyage sur l'élément HTML racine, et de finir par être enterré dans la légende d'un champ profondément nerveux? Il s'agit simplement de suivre les nœuds.
JavaScript n'a pas seulement la possibilité de modifier les éléments existants dans le DOM; Il peut également créer de nouveaux éléments et les placer n'importe où dans la structure d'une page.
Solution
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
La variable Newanchor sera un nouvel élément, prêt à être inséré dans la page.
Spécification des espaces de noms dans des documents avec un type XML MIME
Si vous codiez JavaScript pour une utilisation dans des documents avec un type MIME d'application / xhtml XML (ou un autre type de mime XML), vous devez utiliser la méthode CreateElementns, au lieu de CreateElement, pour spécifier l'espace de noms pour lequel vous créez l'élément:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Cette distinction s'applique à un certain nombre de méthodes DOM, telles que la suppression / retireElementNS et GetAttribute / GetAttributens; Cependant, nous n'utiliserons pas les versions améliorées dans l'espace de noms de ces méthodes dans ce livre.
Simon Willison fournit une brève explication du travail avec JavaScript et différents types de mime sur son site Web.
Le texte qui va à l'intérieur d'un élément est en fait un nœud de texte enfant de l'élément, il doit donc être créé séparément. Les nœuds de texte sont différents des nœuds d'élément, ils ont donc leur propre méthode de création, CreateTextNode:
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">
Si vous modifiez un nœud de texte existant, vous pouvez accéder au texte qu'il contient via la propriété NodeValue. Cela vous permet d'obtenir et de définir le texte à l'intérieur d'un nœud de texte:
<div <br> onmouseover="changeBorder('red')" <br> onmouseout="changeBorder('black')">
La valeur de la variable OldText est désormais "Monoceros", et le texte à l'intérieur de TextNode est maintenant "pyxis".
Vous pouvez insérer un nœud d'élément ou un nœud de texte comme dernier enfant d'un élément existant en utilisant sa méthode APPEDCHILD. Cette méthode placera le nouveau nœud après tous les enfants existants de l'élément.
Considérez ce fragment de HTML:
Example 1.1. separate-content-behaviors.js (excerpt) <br> <br> function changeBorder(element, to) <br> { <br> element.style.borderColor = to; <br> }
Nous pouvons utiliser des méthodes DOM pour créer et insérer un autre lien à la fin du paragraphe:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
La valeur de la variable newchild sera une référence à l'élément nouvellement inséré.
Si nous devions traduire l'état du DOM une fois que ce code a été exécuté en code HTML, cela ressemblerait à ceci:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Nous n'avons spécifié aucun attribution pour le nouvel élément, donc il ne se lie nulle part pour le moment. Le processus de spécification des attributs est expliqué sous peu dans la section appelée «Reading and Writing the Attributs d'un élément».
Discussion
Il existe trois façons de base par lesquelles un nouvel élément ou nœud de texte peut être inséré dans une page Web. L'approche que vous utilisez dépendra du point où vous souhaitez que le nouveau nœud soit inséré: comme dernier enfant d'un élément, avant un autre nœud, ou en remplacement d'un nœud. Le processus d'ajouter un élément au cours du dernier enfant a été expliqué ci-dessus. Vous pouvez insérer le nœud avant un nœud existant à l'aide de la méthode INSERTBEAFARE de son élément parent, et vous pouvez remplacer un nœud en utilisant la méthode RemplaceChild de son élément parent.
Afin d'utiliser InsertBefore, vous devez avoir des références au nœud que vous allez insérer et au nœud avant que vous souhaitez l'insérer. Considérez ce code HTML:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Nous pouvons insérer un nouveau lien avant celui existant en appelant InsertBear à partir de son élément parent (le paragraphe):
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">
La valeur de la variable newchild sera une référence à l'élément nouvellement inséré.
Si nous devions traduire en html l'état du DOM après cette opération, cela ressemblerait à ceci:
<div <br> onmouseover="changeBorder('red')" <br> onmouseout="changeBorder('black')">
Au lieu de cela, nous pourrions remplacer le lien existant entièrement à l'aide de RemplaceChild:
Example 1.1. separate-content-behaviors.js (excerpt) <br> <br> function changeBorder(element, to) <br> { <br> element.style.borderColor = to; <br> }
Le DOM ressemblerait alors à ceci:
<div >
Vos listes commandées se sentent-elles un peu ordonnées? Vos titres ont-ils une envie de paragraphe? En utilisant un peu de connaissances JavaScript, il est possible de modifier entièrement le type d'un élément, tout en préservant la structure de ses enfants.
Solution
Il n'y a pas de moyen simple et simple de modifier le type d'un élément. Pour réaliser cet exploit, vous devrez effectuer un peu de jonglage.
Supposons que nous voulons changer ce paragraphe en div:
Example 1.2. separate-content-behaviors.js <br> <br> function changeBorder(element, to) <br> { <br> element.style.borderColor = to; <br> } <br> <br> var contentDiv = document.getElementById('content'); <br> <br> contentDiv.onmouseover = function() <br> { <br> changeBorder('red'); <br> }; <br> <br> contentDiv.onmouseout = function() <br> { <br> changeBorder('black'); <br> };
Nous devons créer une nouvelle div, déplacer chacun des enfants du paragraphe, puis échanger le nouvel élément contre l'ancien:
window.onload = function() <br> { <br> var contentDiv = document.getElementById('content'); <br> <br> ... <br> };
La seule ligne inconnue ici devrait être le point où un clone est créé pour chacun des enfants du paragraphe. La méthode Clonenode produit une copie identique du nœud à partir duquel il est appelé. En transmettant cette méthode l'argument vrai, nous indiquons que nous voulons que tous les enfants de cet élément soient copiés avec l'élément lui-même. En utilisant Clonenode, nous pouvons refléter les enfants de l'élément d'origine sous le nouveau div, puis supprimer le paragraphe une fois que nous avons fini de copier.
Bien que les nœuds de clonage soient utiles dans certaines circonstances, il s'avère qu'il existe un moyen plus propre d'approcher ce problème spécifique. Nous pouvons simplement déplacer les nœuds enfants du paragraphe existant dans la nouvelle div. Les nœuds DOM ne peuvent appartenir qu'à un seul élément parent à la fois, donc l'ajout des nœuds à la div les supprime également du paragraphe:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Prenez soin de changer la structure du nœud du dom
Les éléments d'une collection sont mis à jour automatiquement chaque fois qu'un changement se produit dans le DOM - même si vous copiez cette collection en une variable avant que le changement ne se produise. Donc, si vous retirez de l'élément DOM et contenu dans une collection avec laquelle vous aviez travaillé, la référence de l'élément sera également supprimée de la collection. Cela modifiera la longueur de la collection ainsi que les index de tous les éléments qui apparaissent après l'élément supprimé.
lors de l'exécution d'opérations qui affectent la structure du nœud du DOM - comme le déplacement d'un nœud vers un nouvel élément parent - vous devez faire attention aux processus itératifs. Le code ci-dessus utilise une boucle de temps qui n'accède que le premier enfant du paragraphe, car chaque fois qu'un enfant est relocalisé, la longueur de la collection ChildNodes diminuera et tous les éléments de la collection évolueront. Une boucle pour une variable de comptoir ne gérerait pas tous les enfants correctement car il supposerait que le contenu de la collection resterait le même tout au long de la boucle.
Discussion
Il n'y a pas de moyen facile de copier les attributs d'un élément à son remplacement. (Si vous regardez la spécification DOM, il semble que ce soit.
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>Retirer un élément ou un nœud de texte
Solution
La méthode RemoveChild supprime tout nœud enfant de son parent et renvoie une référence à l'objet supprimé.Commençons par ce html:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>Nous pourrions utiliser Removechild pour supprimer le lien hypertexte de son paragraphe parent comme:
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">La variable supprimée sera une référence à l'élément A, mais cet élément ne sera situé nulle part dans le DOM: il sera simplement disponible en mémoire, tout comme si nous venions de le créer en utilisant CreateElement. Cela nous permet de le déplacer sur une autre position sur la page, que nous le souhaitons, ou nous pouvons simplement laisser la variable disparaître à la fin du script, et la référence sera complètement perdue - la supprimer efficacement. Suivant le code ci-dessus, le DOM finira comme ceci:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Bien sûr, vous n'avez pas besoin d'attribuer la valeur de retour de RemoveChild à une variable. Vous pouvez simplement l'exécuter et oublier complètement l'élément:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Discussion
Si l'élément que vous supprimez a des enfants que vous souhaitez préserver (c'est-à-dire que vous voulez simplement les «déballer» en supprimant leur parent), vous devez sauver ces enfants pour vous assurer qu'ils restent dans le document lorsque leur parent est enlevé. Vous pouvez y parvenir en utilisant la méthode INSERTBEFORE AFFERNE déjà mentionnée, qui, lorsqu'elle est utilisée sur des éléments qui sont déjà contenus dans le DOM, les supprime d'abord, puis les insère au point approprié.
Le paragraphe du HTML suivant contient plusieurs enfants:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Nous pouvons parcourir la collection de nodes ChildNodes du paragraphe et déplacer chacun de ses enfants individuellement avant de retirer l'élément lui-même:
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">
Le dom de la page ressemblera maintenant à ceci:
<div <br> onmouseover="changeBorder('red')" <br> onmouseout="changeBorder('black')">
Les parties les plus fréquemment utilisées d'un élément HTML sont ses attributs? Son ID, sa classe, HREF, son titre ou une centaine d'autres informations qui peuvent être incluses dans une balise HTML. JavaScript est capable non seulement de lire ces valeurs, mais d'écrire également.
Solution
Deux méthodes existent pour lire et écrire les attributs d'un élément. GetAttribute vous permet de lire la valeur d'un attribut, tandis que SetAttribute vous permet de l'écrire.
Considérez ce html:
Example 1.1. separate-content-behaviors.js (excerpt) <br> <br> function changeBorder(element, to) <br> { <br> element.style.borderColor = to; <br> }
Nous serions en mesure de lire les attributs de l'élément comme SO:
<div >
La valeur de la variable Anchorid sera "Antares", et la valeur de l'ancienne variable sera "un endroit lointain".
Pour modifier les attributs de l'hyperlien, nous utilisons SetAttribute, en le passant le nom de l'attribut à modifier, et la valeur que nous voulons la modifier:
Example 1.2. separate-content-behaviors.js <br> <br> function changeBorder(element, to) <br> { <br> element.style.borderColor = to; <br> } <br> <br> var contentDiv = document.getElementById('content'); <br> <br> contentDiv.onmouseover = function() <br> { <br> changeBorder('red'); <br> }; <br> <br> contentDiv.onmouseout = function() <br> { <br> changeBorder('black'); <br> };
La valeur de la variable newtitle sera désormais "pas si loin".
Discussion
Dans son parcours, du Wilderness de NetScape en liberté au plus étroitement, le terrain plus défini et basé sur les normes de l'ère moderne, la norme DOM a ramassé une bonne quantité de syntaxe supplémentaire pour faire face à HTML. L'une des plus omniprésentes de ces extras est la cartographie entre les propriétés DOM et les attributs HTML.
Lorsqu'un document est analysé dans sa forme DOM, des nœuds d'attribut spéciaux sont créés pour les attributs d'un élément. Ces nœuds ne sont pas accessibles en tant que «enfants» de cet élément: ils ne sont accessibles que via les deux méthodes mentionnées ci-dessus. Cependant, en tant que retour aux implémentations DOM originaux (appelé Dom 0, où le zéro suggère que ces fonctionnalités sont venues avant les normes), les spécifications DOM actuelles contiennent des fonctionnalités supplémentaires spécifiques à HTML. En particulier, les attributs sont accessibles directement en tant que propriétés d'un élément. Ainsi, l'attribut HREF d'un hyperlien est accessible via link.getAttribute ("href") ainsi que via link.href.
Cette syntaxe de raccourci n'est pas seulement plus propre et plus lisible: dans certaines situations, elle est également nécessaire. Internet Explorer 6 et les versions ci-dessous ne propageront pas les modifications apportées via SetAttribute à l'affichage visuel d'un élément. Ainsi, toutes les modifications apportées à la classe, ID ou le style d'un élément utilisant SetAttribute n'affecteront pas la façon dont il est affiché. Pour que ces modifications prennent effet, ils doivent être effectués via les propriétés spécifiques à l'attribut du nœud élément.
Pour confondre davantage les choses, les valeurs qui sont renvoyées lorsqu'une propriété spécifique à l'attribut est lue varie entre les navigateurs, les variations les plus notables se produisant à Konqueror. Si un attribut n'existe pas, Konqueror renverra NULL comme valeur d'une propriété spécifique à l'attribut, tandis que tous les autres navigateurs renverront une chaîne vide. Dans un cas plus spécifique, certains navigateurs renverront Link.getAttribute ("HREF") en tant qu'URL absolue (par exemple, "http://www.example.com/antares.html"), tandis que d'autres renvoient la valeur d'attribut réelle (par exemple, "antares.html"). Dans ce cas, il est plus sûr d'utiliser la propriété DOT, car il renvoie systématiquement l'URL absolue entre les navigateurs.
Alors, quelle est la solution générale à ces problèmes?
La règle de base est la suivante: si vous êtes certain qu'un attribut a reçu une valeur, il est sûr d'utiliser la méthode de la propriété DOT pour y accéder. Si vous ne savez pas si un attribut a été défini ou non, vous devez d'abord utiliser l'une des méthodes DOM pour vous assurer qu'elle a une valeur, puis utilisez la propriété DOT pour obtenir sa valeur.
Pour Reading Un attribut non vérifié, utilisez ce qui suit:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Cela garantit que l'attribut existe, et n'est pas nul, avant de récupérer sa valeur.
Pour Écriture à un attribut non vérifié, utilisez le code suivant:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Ce code s'assure que l'attribut est créé correctement d'abord, et est ensuite défini de manière à ce qu'Internet Explorer n'ait pas de problèmes si l'attribut affecte l'affichage visuel de l'élément.
Cette règle a quelques exceptions près des attributs dont vous pouvez garantir l'existence. Les attributs les plus notables de ces «incontournables» sont le style et la classe, qui seront toujours valables pour un élément donné; Ainsi, vous pouvez immédiatement les référencer sous forme de propriétés DOT (élément.style et élément.classname respectivement).
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
L'autre attribut que nous devons surveiller est l'attribut pour une étiquette. Il suit les mêmes règles que la classe, mais son formulaire de propriété est htmlfor. En utilisant getAttribute / setAttribute, nous écrivons element.getAttribute ("pour"), mais dans Internet Explorer, il est élément.getAttribute ("htmlfor").
La possibilité de trouver tous les éléments qui ont un attribut particulier peuvent être assez utiles lorsque vous devez modifier tous les éléments qui ont la même classe ou le même titre, par exemple.
Solution
Afin de trouver des éléments avec une valeur d'attribut particulière, nous devons vérifier chaque élément de la page pour cet attribut. Il s'agit d'un fonctionnement très à forte intensité de calcul, il ne devrait donc pas être entrepris légèrement. Si vous vouliez trouver tous les éléments d'entrée avec TYPE = "Checkbox", vous feriez mieux de limiter votre recherche aux éléments d'entrée en premier:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Cela nécessitera moins de calcul que d'itérer à travers chaque élément de la page et de vérifier son type. Cependant, la fonction présentée dans cette solution - GetElementsByAttribute - est idéale lorsque vous devez trouver un certain nombre d'éléments de différents types qui ont la même valeur d'attribut.
Le moyen le plus simple de vérifier chaque élément d'une page est de faire un peu de parcourir la collection renvoyée par GetElementsByTagname ("*"). Le seul problème avec cette méthode est qu'Internet Explorer 5.0 et 5.5 ne prennent pas en charge le jenkcard Asterisk pour la sélection de balises. Heureusement, ces navigateurs prennent en charge le document. GetElementsByAttribute gère ce problème avec une branche de code simple, puis procède à vérifier les éléments d'une valeur d'attribut donnée, ajoutant des correspondances à un tableau à retourner:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Une grande partie du code dans GetElementsByAttribute traite les différences de navigateur dans la gestion des attributs qui ont été mentionnés plus tôt dans ce chapitre, dans la section intitulée «Reading and Writing the Attributs of a Element». Les techniques nécessaires sont utilisées si l'attribut requis est classe ou pour. En tant que bonus supplémentaire lors de la vérification d'une correspondance sur l'attribut de classe, si un élément a été attribué plusieurs classes, la fonction vérifie automatiquement chacun de ces éléments pour voir s'il correspond à la valeur requise.
combiner plusieurs classes est une technique CSS très utile. Il fournit un moyen très primitif d'héritage en permettant à un certain nombre de styles différents d'être combinés sur un élément, vous permettant de mélanger et de faire correspondre différents effets sur un site. Ils sont particulièrement utiles dans des situations comme la mise en évidence des éléments: une classe peut être ajoutée qui met en évidence un élément sans déranger aucune des autres propriétés visuelles qui peuvent avoir été appliquées à l'élément par d'autres classes. Cependant, si vous attribuez des classes en JavaScript, vous devez faire attention à ne pas écraser par inadvertance des classes précédemment assignées.
Solution
La classe pour tout élément est accessible via sa propriété ClassName. Cette propriété vous permet à la fois de lire et d'écrire les classes qui sont actuellement appliquées à cet élément. Parce que c'est juste une chaîne, la partie la plus difficile de travailler avec ClassName est que vous devez gérer la syntaxe qu'il utilise pour représenter plusieurs classes.
Les noms de classe dans la propriété ClassName d'un élément sont séparés par des espaces. Le premier nom de classe n'est précédé de rien, et le dernier nom de classe n'est suivi de rien. Cela facilite l'ajout d'une classe à la liste de classe naïvement: concaténez simplement un espace et le nouveau nom de classe à la fin de ClassName. Cependant, vous voudrez éviter d'ajouter un nom de classe qui existe déjà dans la liste, car cela rendra la suppression de la classe plus difficile. Vous voudrez également éviter d'utiliser un espace au début de la valeur de classe, car cela entraînera des erreurs dans l'opéra 7:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Tout d'abord, AddClass crée un modèle d'expression régulière contenant la classe à ajouter. Il utilise ensuite ce modèle pour tester la valeur de nom de classe actuelle. Si le nom de classe n'existe pas déjà, nous vérifions une valeur de nom de classe vide (auquel cas le nom de classe est attribué à la propriété textuellement), ou nous ajoutons à la valeur existante un espace et le nouveau nom de classe.
Classes de séparation
Certains exemples d'expression réguliers pour trouver des classes utilisent le caractère spécial de la limite (b) pour séparer les classes. Cependant, cela ne fonctionnera pas avec tous les noms de classe valides, tels que ceux contenant des traits de traits.
Le processus de suppression d'une classe utilise un modèle d'expression régulière identique à celui que nous utilisons pour ajouter une classe, mais nous n'avons pas besoin d'effectuer autant de chèques:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Une fois que RemoveClass a exécuté l'expression régulière de remplacement sur une copie de la valeur de la propriété ClassName, il nettoie la valeur résultante en supprimant tout espace de fuite (qui est créé lorsque nous supprimons la dernière classe dans un nom de classe multiple), puis la affecte au nom de classe de la cible.
Ce chapitre a introduit les outils de base mais puissants dont vous aurez besoin pour manipuler le modèle d'objet de document. Il est important que vous compreniez le Dom - le squelette sous tout ce que vous voyez dans un navigateur - lorsque vous manipulez n'importe quelle page Web. Savoir créer, modifier et supprimer des parties du DOM est crucial pour comprendre le reste de ce livre. Une fois que vous aurez maîtrisé ces techniques, vous serez bien sur le point de devenir un programmeur JavaScript.
Ce chapitre concerne la manipulation simple des fenêtres et des cadres, y compris des tâches comme l'ouverture des fenêtres contextuelles, la communication entre les cadres (les techniques impliquées dans la lecture des données d'un iframe seront couvertes dans le chapitre 18, créant des applications Web avec Javascript.) Et découvrir la position de défilement de la page.
Beaucoup de gens estiment que la manipulation des fenêtres s'apparente au côté obscur. Ils croient qu'une fenêtre fait partie de l'interface graphique de l'utilisateur, pas du document, et puisque JavaScript est un langage de script de document, il n'a pas d'affaires de manipulation de Windows.
Je suis généralement enclin à être d'accord, mais je sais que l'opinion est parfois un luxe. Si vos clients demandent quelque chose de spécifique, vous ne pouvez pas nécessairement changer d'avis ou avoir la liberté de refuser le travail sur la base d'un tel principe. Dans ce chapitre, nous couvrirons une gamme de tâches pratiques de manipulation de fenêtres et de cadre tout en restant sensible aux problèmes d'utilisation et d'accessibilité qui peuvent découler de leur utilisation.
Notez, cependant, qu'il existe des limites, et certaines variétés de scripts de fenêtres sont particulièrement hostiles. Nous ne traiterons pas de tactiques agressives comme la fermeture ou la modification de la fenêtre principale de l'utilisateur, le déplacement des fenêtres autour de l'écran ou l'ouverture des fenêtres en plein écran ou «sans chroméles». Ce sont exactement les types d'abus qui ont donné à JavaScript une mauvaise réputation.
Grâce à la majeure partie de ce chapitre, nous examinerons attentivement les propriétés et les méthodes de l'objet Window. Ceux-ci sont mis en œuvre par différents navigateurs de diverses manières, dont la plupart sont utilisés depuis les jours avant la normalisation de JavaScript.
Nous aurons pas mal de branches de code à gérer, mais nous éviterons le reniflement du navigateur redouté par une utilisation minutieuse de la détection d'objet, le processus de détection d'un objet ou d'une fonctionnalité pour tester la compatibilité, plutôt que de détecter des navigateurs spécifiques.
devriez-vous utiliser des fenêtres contextuelles? La réponse la plus considérée que j'ai est la suivante: pas si vous pouvez l'aider. Les fenêtres popup ont acquis une mauvaise réputation de l'utilisation agressive par les spécialistes du marketing, mais même les popups ont demandé que les popups peuvent être des obstacles à une bonne convivialité.
Je ne dirai pas que les popups ne sont jamais appropriés, mais je dirai qu'ils sont rarement ainsi. Néanmoins, il existe des situations où les écarts d'ouverture d'une nouvelle fenêtre sont sans doute la solution la plus appropriée: une enquête en ligne pourrait être un exemple, car le format peut rendre le contenu plus accessible; Les jeux DHTML en sont un autre, car la fenêtre peut devoir être de taille connue.
Je qualifierai mon opinion en discutant des problèmes que les fenêtres créent, puis en fournissant une méthode pragmatique pour les utiliser qui atténue ces problèmes autant que possible.
Qu'est-ce qui ne va pas avec les popups?
Le principal problème avec la plupart des scripts de fenêtres contextuels est qu'ils ne considèrent pas les besoins de l'utilisateur? Ils répondent uniquement aux besoins du concepteur. Les résultats? Nous les avons tous vus:
Ces problèmes ne sont pas seulement des questions de convivialité, mais aussi de l'accessibilité. Par exemple, les utilisateurs de lecture d'écran ne peuvent pas être informés par leurs appareils qu'une nouvelle fenêtre s'est ouverte. Cela pourrait évidemment provoquer une confusion s'ils tentaient ensuite de retourner dans l'histoire du navigateur (ils ne le peuvent pas). La même chose peut se produire pour un utilisateur voyant si une fenêtre s'ouvre à la taille complète: vous et moi connaissons peut-être l'utilisation de la barre des tâches pour surveiller les fenêtres ouvertes, mais tous les utilisateurs d'ordinateurs - ils peuvent même ne pas se rendre compte qu'une nouvelle fenêtre est apparue.
Si vous allez utiliser des popups, en recherchant des problèmes comme ceux-ci et être généralement sensible à leurs impacts, rendra vos popups plus conviviales pour les utilisateurs, et moins une pression sur votre conscience.
Aussi, gardez à l'esprit que, du point de vue d'un développeur, les fenêtres contextuelles ne sont pas garanties pour fonctionner: la plupart des navigateurs incluent désormais des options pour supprimer les fenêtres contextuelles, et dans certains cas, la suppression se produit même si la fenêtre contextuelle est générée en réponse à un événement utilisateur.
Vous pourrez peut-être le permettre comme vous le feriez pour les situations dans lesquelles les scripts n'étaient pas pris en charge: en vous assurant que le déclencheur sous-jacent de la fenêtre contextuelle fait toujours quelque chose d'utile si la fenêtre contextuelle échoue. Ou vous pouvez demander à votre code d'ouvrir une fenêtre, puis de vérifier sa propre propriété fermée, pour voir si elle est réellement affichée (nous examinerons cette technique dans la solution suivante).
Mais aucune de ces approches n'est garantie de fonctionner avec chaque navigateur et bloqueur contextuel, donc pour cela autant que les raisons d'utilisation, il est plus simple et mieux d'éviter d'utiliser des popups chaque fois que vous le pouvez.
Comment minimiser les problèmes?
Ce que nous devons faire, c'est établir des règles d'or pour l'utilisation éthique des popups:
Solution
Voici une fonction de contexte générique basée sur les directives ci-dessus:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
En plus de limiter la taille de la fenêtre, ce script refuse de créer une fenêtre contextuelle qui n'a pas de débordement, donc si vous ne spécifiez pas "défiler", "redimensionner" ou "les deux" pour l'argument de débordement, le paramètre par défaut de "les deux" sera utilisé.
L'opérateur ternaire
Ce script utilise une expression de raccourci appelée opérateur ternaire pour évaluer chacune des options de débordement. L'opérateur ternaire utilise? et: caractères pour diviser les deux résultats possibles d'une évaluation, et équivaut à une seule paire de conditions if..else. Considérez ce code:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Ce code est équivalent au balisage ci-dessous:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Les parenthèses ne sont pas nécessaires, mais vous pouvez constater qu'elles rendent l'expression plus facile à lire. Pour en savoir plus sur cela et d'autres raccourcis utiles, voir le chapitre 20, en suivant le rythme.
Une fois que vous avez la fonction popup en place, vous pouvez l'appeler de diverses manières. Par exemple, vous pouvez utiliser un lien régulier:
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">
Si le script n'est pas disponible, cela fonctionnera comme n'importe quel autre lien, mais si le script est disponible, le script peut déclencher un gestionnaire d'événements de clic qui transmet son HREF à la fonction MakePopup, ainsi que les autres paramètres. La valeur de retour du gestionnaire dépend de l'ouverture ou non de la fenêtre; Les navigateurs qui bloquent la fenêtre contextuelle suivront le lien comme d'habitude:
<div <br> onmouseover="changeBorder('red')" <br> onmouseout="changeBorder('black')">
En général, si vous avez un script qui nécessite une fenêtre générée, vous pouvez appeler la fonction MakePopup directement avec une URL:
Example 1.1. separate-content-behaviors.js (excerpt) <br> <br> function changeBorder(element, to) <br> { <br> element.style.borderColor = to; <br> }
Si vous devez fermer cette fenêtre plus tard dans votre script, vous pouvez le faire en utilisant la méthode Close sur la référence de la fenêtre stockée:
<div >
Discussion.
La méthode Window.Open peut prendre un certain nombre d'arguments - en plus de l'URL et du nom de la fenêtre - qui spécifient si la fenêtre doit avoir des décorations particulières, telles que la barre de menu, la barre d'outils ou la barre d'adresse (emplacement). Ces arguments sont passés comme une chaîne dédiée à des virgules au troisième argument de Window.Open:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Dans notre fonction MakePopup, le menubar, la barre d'outils et les arguments de localisation sont tous prédéfinis pour non, car ces éléments sont rarement utiles pour les fenêtres contextuelles - ce sont des outils de navigation, après tout. Les fenêtres contextuelles sont principalement utilisées pour les interfaces d'une page, ou celles dans lesquelles la navigation historique est découragée, comme notre exemple d'enquête, ou la procédure de connexion pour le site Web d'une banque.
Vous pouvez modifier ces arguments si vous en avez besoin, mais l'argument de statut doit toujours être défini sur OUI, car le désactiver sape une bonne convivialité. (Je sais - je l'ai déjà mentionné, mais je le répose à nouveau parce que c'est important!)
L'argument redonnable peut ne pas avoir d'effet - dans certains navigateurs, soit par conception, soit en raison des préférences de l'utilisateur, il n'est pas possible de créer des fenêtres non résistantes, même si vous définissez cette valeur sur non. En fait, dans Opera 8 pour Mac OS X, il n'est pas possible de créer des fenêtres de taille personnalisée - une fenêtre créée apparaîtra comme un nouvel onglet dans la fenêtre actuelle. Cette exception spécifique n'est peut-être pas significative en soi, mais elle sert à illustrer le point général que le contrôle des propriétés d'une fenêtre créée n'est pas absolument garanti.
Une fois qu'une nouvelle fenêtre est ouverte, vous pouvez le mettre au point en utilisant la méthode de mise au point de l'objet. Ce n'est généralement pas nécessaire - généralement, cela se produit par défaut - mais la technique peut être utile lorsque vous scriptez avec plusieurs fenêtres:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Alternativement, vous voudrez peut-être ouvrir une fenêtre contextuelle mais garder le focus dans la fenêtre primaire (créant ainsi un soi-disant «popunder»). Vous pouvez retirer l'attention d'une fenêtre en utilisant sa méthode floue:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Cependant, dans ce cas, vous ne pouvez pas prédire où se concentrera sur la focalisation, il est donc plus fiable de recentrer la fenêtre primaire:
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">
Dans les versions strictes de HTML 4 et XHTML 1, l'attribut cible pour les liens n'existe plus. Une interprétation de ceci est que les pages Web ne devraient tout simplement pas ouvrir des liens dans les nouvelles fenêtres; Un autre est que le ciblage n'a pas de sémantique universelle et ne devrait donc pas être défini dans HTML. (Le projet de travail CSS 3 comprend un ensemble de propriétés cibles pour la présentation de liens, qui pourrait éventuellement voir ce mécanisme remis à CSS à la place. Personnellement, j'espère que cela ne dépasse jamais la scène du projet, car cela n'a rien à voir avec CSS: le contrôle de l'interface n'est pas plus approprié dans un langage de conception que dans un langage de marquage sémantique!)
Il y a d'autres interprétations, et les arguments sont longs (et parfois fastidieux), mais il suffit de dire que vous pouvez avoir besoin d'une solution à ce problème. Quels que soient vos opinions personnelles, c'est une demande courante de clients de développement Web.
Solution
Ce script identifie les liens par la valeur d'attribut rel externe. L'attribut rel est un moyen de décrire la relation entre un lien et sa cible, donc son utilisation pour identifier les liens qui pointent vers un autre site est sémantiquement non dubie:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Si chaque lien externe est identifié comme celui-ci, un seul document. Le gestionnaire d'événements peut traiter des clics sur tous ces liens:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Discussion
L'utilisation d'un seul gestionnaire d'événements à l'échelle du document est l'approche la plus efficace - c'est bien mieux que d'itréger tous les liens et de lier un gestionnaire à chacun individuellement. Nous pouvons découvrir quel élément a été réellement cliqué en faisant référence à la propriété cible de l'événement. Pour en savoir plus sur les événements et les propriétés des événements, voir le chapitre 13, HTML dynamique de base, mais voici un bref résumé de la situation.
Deux modèles d'événements complètement différents sont utilisés par les navigateurs actuels. Le script établit lequel doit être utilisé en recherchant E - l'argument de l'événement qui est utilisé par les navigateurs de Mozilla, et a été adopté par la plupart des autres navigateurs - par opposition à l'objet Window.Event utilisé par Internet Explorer. Il enregistre ensuite la propriété de l'objet qui est approprié au modèle utilisé: soit la cible pour Mozilla et les navigateurs, ou le srcelement pour IE.
L'objet cible (si elle n'est pas nul) peut être l'une des trois choses: un nœud d'élément de liaison, un élément ou un nœud de texte dans un lien ou un autre nœud. Nous voulons que les deux premiers cas des deux premiers soient gérés par notre script, mais les clics provenant de la dernière situation peuvent être ignorés en toute sécurité. Ce que nous faisons, c'est suivre la piste des nœuds parents de la cible de l'événement jusqu'à ce que nous trouvions un lien, soit accéder à l'élément corporel.
Une fois que nous avons un lien cible unifié, nous devons simplement vérifier un attribut rel avec la valeur correcte; S'il existe, nous pouvons ouvrir une fenêtre avec le HREF du lien, et si tout cela est réussi (à juger par la propriété fermée du nouvel objet de fenêtre), le gestionnaire reviendra faux, empêchant le lien d'origine d'être suivi.Passer un lien vers Window.Open sans définir des arguments créera une fenêtre avec des décorations par défaut - tout comme un lien avec Target = "_ Blank".
le premier test
Nous utilisons GetAttribute comme premier test pour rel car les propriétés spécifiques à l'attribut ne sont fiables que si vous savez avec certitude que l'attribut en question a été attribué une valeur. Nous ne pouvons pas aller directement à tester Target.rel contre une chaîne, car il peut être nul ou indéfini. Cela a été discuté plus en détail dans la section appelée «Reading and Writing the Attributs of a Element».
communiquer entre les images
Si vous avez le choix de savoir si vous devez ou non utiliser des cadres, je vous conseillerais fortement de le faire, car ils ont de nombreux problèmes de convivialité et d'accessibilité graves, tout à fait en dehors du fait qu'ils sont conceptuellement brisés (ils créent au sein des états de navigateur qui ne peuvent pas être traités). Mais comme pour votre utilisation des fenêtres contextuelles, dans certains cas, vous n'avez peut-être pas le choix de votre utilisation des cadres. Donc, si vous devez vraiment les utiliser, voici ce que vous devrez faire.
Solution
Commençons par un simple document de jeu de cadres:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Nous pouvons utiliser quatre références pour les scripts croisés:
Disons que nous avons un script dans ContentFrame qui veut communiquer la page dans NavigationFrame. Les deux pages sont contenues dans un seul immeuble - la seule dans la hiérarchie - nous pourrions donc faire avec succès l'une des références suivantes à partir de ContentFrame:
La collection Frames est un tableau associatif (comme la collection Forms que nous avons vue dans le chapitre 6, les formulaires de traitement et de validation), de sorte que chaque élément est accessible par index ou nom. Il est généralement préférable d'utiliser le nom (sauf si vous avez une bonne raison de ne pas le faire) afin que vous n'ayez pas à modifier votre code plus tard si la commande de trame change. De même, les références parentales dans un trame imbriqué complexe peuvent changer si la hiérarchie change, donc je recommande généralement que les développeurs commencent toujours à se référer par le haut. Parmi les options ci-dessus, la référence que je préfère, alors, est en haut.
Maintenant que nous avons une référence au cadre, nous pouvons appeler une fonction dans l'autre page encadrée:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>Alternativement, nous pouvons obtenir une référence à l'autre document encadré et travailler avec le DOM à partir de là:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Discussion
La communication entre les cadres n'est autorisée que pour des documents dans le même domaine - pour des raisons de sécurité, il n'est pas possible de travailler avec un document chargé à partir d'un domaine différent de celui du script. Il ne ferait pas, par exemple, un propriétaire de site malveillant pour charger un site que vous visitez régulièrement dans un cadre et volez les données personnelles que vous y entrez.En fait, certains navigateurs permettent aux utilisateurs de refuser tous les scripts de communiquer entre les cadres, juste pour éradiquer toute possibilité d'une vulnérabilité de script de site croisée, et il n'y a aucun moyen de contourner cette préférence si votre script se trouve en cours d'exécution dans un navigateur ainsi configuré.
Si vous avez des utilisateurs qui se plaignent de problèmes (et ils ne peuvent pas ou ne modifieront pas leurs paramètres pour permettre des scripts croisés), la chose la plus sûre à faire est simplement d'éviter complètement les scripts.
Les méthodes alternatives de passage des données entre les pages sont discutées dans le chapitre 6, le traitement et la validation des formulaires et le chapitre 8, en travaillant avec les cookies.Obtenir la position de défilement
Solution
Il existe trois façons d'obtenir ces informations. Nous utiliserons des tests d'objets sur chaque approche, pour déterminer le niveau de support disponible:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>La fonction peut désormais être appelée selon les besoins. Voici une démonstration simple, en utilisant une fenêtre.
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>Le problème avec le défilement
Le défilement n'est pas le plus fiable des événements: il peut ne pas tirer du tout dans Konqueror ou Safari 1.0, ou lorsque l'utilisateur navigue avec une roue de souris dans Firefox. Et s'il se déclenche, il peut le faire continuellement et rapidement (comme il le fait dans Internet Explorer), qui peut être lent et inefficace si le script que vous avez défini pour répondre à l'événement est très complexe.
Si vous avez des difficultés de ce type, vous pouvez trouver mieux d'utiliser la fonction SetInterval au lieu d'un gestionnaire d'événements Onscroll. SetInterval vous permettra d'appeler la fonction à un intervalle prévisible, plutôt qu'en réponse à un événement. Vous pouvez en savoir plus sur ce type de script dans le chapitre 14, le temps et le mouvement, mais voici un exemple comparable:
window.setinterval (function ()
{
var scrollPos = getCrollingPosition ();
document.title = 'Left =' scrollPos [0] 'top ='
ScrollPos [1];
}, 250);
La seule véritable complication ici est que IE 5 reconnaît réellement la propriété DocumentElement.ScrollTop, mais sa valeur est toujours nulle, nous devons donc vérifier la valeur ainsi que la recherche de l'existence de la propriété.
Sinon, il n'a pas vraiment d'importance pour nous quel navigateur utilise quelle propriété; Tout ce qui compte, c'est que notre script passe par l'un des tests de compatibilité et renvoie une valeur utile. Cependant, les propriétés utilisées par chaque navigateur sont présentées ici pour référence:
Cette liste ne raconte pas l'histoire complète, mais elle est principalement destinée à décrire l'ordre des tests. Les navigateurs de Mozilla plus récents (tels que Firefox) prennent également en charge DocumentElement.ScrollTop et Body.ScrollTop, par les mêmes règles de mode de rendu que IE 6. Safari et Konqueror Support Body.Scrolltop dans les deux mode. L'opéra prend en charge les trois propriétés dans n'importe quel mode!
Mais rien de tout cela n'est important pour vous de savoir - les fournisseurs de navigateurs ajoutent ces multiples propriétés pour permettre des scripts qui ne sont pas au courant d'une propriété ou d'une autre, pour ne pas fournir de choix arbitraires pour le bien. De notre point de vue, le point important est de s'installer sur un ensemble de tests de compatibilité qui garantissent que notre script fonctionnera le plus largement possible.
Modes de rendu
Le mode «Normes» et le mode «Quirks» sont les deux principaux modes de rendu utilisés par les navigateurs actuels. Ces modes affectent divers aspects du document de sortie, y compris quel élément est la toile ( ou ), et comment les tailles de boîtes CSS sont calculées. Pour en savoir plus sur les modes de rendu, voir le chapitre 11, détecter les différences de navigateur.
Tous les navigateurs actuels implémentent les mêmes méthodes (non standard) pour faire défiler une page. Au moins quelque chose ici est simple!
Solution
Il existe deux méthodes qui peuvent être utilisées pour faire défiler la page (ou plutôt la fenêtre ou le cadre), soit par un montant particulier (Window.Scrollby), soit à un point particulier (Window.Scrollto):
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Ces exemples disent: faites défiler vers le bas de 200 pixels, puis par 200 pixels, puis à un point de 300 pixels de la gauche et à 100 pixels du haut, puis de retour dans le coin supérieur.
Les détails de la taille de la fenêtre sont nécessaires pour de nombreux types de scripts, partout où l'espace disponible est un facteur dans la logique du script. Cette solution fournit une fonction utilitaire pour obtenir la taille de la fenêtre, nous reverrons la fonction à plusieurs reprises dans ce livre!
Solution
Les propriétés dont nous avons besoin sont implémentées de trois manières différentes, comme les propriétés que nous avons vues pour le défilement de la page dans la section précédente (la section appelée «Faire défiler la page vers une position particulière»). Comme ce fut le cas dans cet exemple, nous pouvons utiliser des tests d'objets pour déterminer quelle implémentation est pertinente, y compris le test pour une valeur zéro dont nous avons besoin dans IE 5 (ce test est requis pour la même raison: parce que, bien que la propriété existe, ce n'est pas ce que nous voulons):
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
La fonction renvoie un tableau de la largeur et de la hauteur, afin que nous puissions l'appeler chaque fois que nous avons besoin de ces données:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Nous avons couvert les bases de la manipulation des fenêtres et des cadre du point de vue d'un pragmatiste dans ce chapitre. Nous avons également parlé des principes et des techniques que nous pouvons utiliser pour nous assurer que des scripts comme celui-ci sont aussi conviviaux et aussi accessibles que possible. Sans aucun doute, ce type de travail restera controversé, et nous avons clairement besoin d'une sorte de mécanisme de ciblage, car même si l'utilisation des cadres s'éteint lentement, l'avènement d'interfaces toujours plus sophistiquées maintient ces problèmes en vie.
J'aime plutôt l'attribut Show de la standard Xlink, qui a des valeurs comme neuves et remplacer. Ceux-ci suggèrent un processus cible (ouvrez une nouvelle fenêtre et remplacez le contenu de la fenêtre actuelle, respectivement), mais ils ne définissent pas réellement des comportements spécifiques. Ils laissent l'agent utilisateur pour contrôler ce qui se passe réellement, donc, par exemple, New pourrait être utilisé pour ouvrir des onglets au lieu de Windows.
Dynamic HTML n'est pas une seule technologie que vous pouvez indiquer et dire: "C'est DHTML." Le terme est un descripteur qui englobe toutes les technologies qui combinent pour rendre une dynamique de page Web: les technologies qui vous permettent de créer de nouveaux éléments sans rafraîchir la page, modifier la couleur de ces éléments et les faire se développer, se contracter et zoomer autour de l'écran.
DHTML utilise HTML, le DOM et CSS en combinaison avec un langage de script côté client - JavaScript - pour donner vie à ce qui était traditionnellement un support statique. Dans les chapitres précédents, nous avons appris que nous pouvons utiliser JavaScript pour manipuler des parties d'une page pour obtenir des résultats très pratiques. DHTML fournit des solutions à des problèmes beaucoup plus complexes en assemblant ces parties en un ensemble cohérent - celui qui satisfait les besoins du monde réel, plutôt que la programmation de puzzles.
Ce chapitre explore quelques-uns des outils dont nous avons besoin afin de créer des interfaces utilisateur efficaces avec DHTML. Il discute ensuite de quelques widgets simples en préparation des modules les plus complexes que nous considérerons tout au long du reste de ce livre.
Toute interaction que les utilisateurs ont avec une page Web - qu’ils déplacent la souris ou que le clavier apprenne le clavier - amènera le navigateur à générer un événement. Parfois, nous voulons que notre code réponde à cette interaction, nous écoutons donc ces événements, ce qui nous fait savoir quand nous devons exécuter notre code.
Solution
Il existe deux façons de gérer les événements: la courte voie et la manière W3C. Chacun a ses avantages et ses inconvénients, mais les deux vous permettent d'exécuter une fonction spécifiée lorsqu'un événement se produit sur un élément particulier.
The Short Way: Utilisation des gestionnaires d'événements
La façon plus courte de gérer un événement consiste à utiliser les gestionnaires d'événements DOM 0 qui sont attribués comme propriétés de raccourci de chaque élément. Tout comme nous l'avons vu dans le chapitre 5, en naviguant sur le modèle d'objet de document lorsque nous avons discuté des raccourcis d'attribut DOM 0, ces gestionnaires d'événements ne sont pas à l'épreuve des futurs. Cependant, ils offrent des avantages par rapport aux auditeurs d'événements W3C standard:
Le principal problème de l'utilisation des gestionnaires d'événements DOM 0 est qu'ils ne sont pas conçus pour fonctionner avec plusieurs scripts. Chaque fois que vous attribuez un gestionnaire d'événements DOM 0, vous écrasez tout gestionnaire précédemment affecté pour cet événement. Cela peut interférer avec le fonctionnement de plusieurs scripts qui nécessitent une gestion des événements sur le même élément. Avec les auditeurs d'événements W3C, vous pouvez appliquer n'importe quel nombre d'écouteurs d'événements sur le même élément et profiter de la possibilité de supprimer l'un d'eux à tout moment.
Si vous pouvez être certain que votre code n'interférera pas avec la gestion des événements de quelqu'un d'autre (par exemple, vous placez des événements sur des éléments qui sont créés dynamiquement dans votre propre script), il sera sûr d'utiliser les gestionnaires d'événements DOM 0. Mais - toutes choses étant égales par ailleurs - il est plus sûr d'utiliser les auditeurs d'événements W3C partout où nous le faisons, comme nous le faisons dans ce livre.
Un certain nombre de gestionnaires d'événements DOM 0 sont disponibles via le navigateur; Le tableau 13.1, «Dom 0 Événements» répertorie les gestionnaires les plus couramment utilisés.
Tableau 13.1. Handleurs d'événements DOM 0
En utilisant des gestionnaires d'événements DOM 0, une fois que vous avez une référence à l'élément dont vous souhaitez gérer les événements, il s'agit d'une question simple d'attribuer une fonction de traitement à la propriété appropriée:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Vous remarquerez que, dans l'affectation de la fonction (Button.OnClick = Engage;), les parenthèses ne suivent pas le nom de la fonction. Leur inclusion exécuterait immédiatement la fonction et affecterait la valeur de retour en tant que gestionnaire d'événements. En omettant les parenthèses, vous pouvez attribuer la fonction elle-même au gestionnaire. Cela signifie également que vous ne pouvez pas fournir des arguments directement à la fonction de traitement: la fonction doit obtenir ses informations par d'autres moyens.
fonctions anonymes
Au lieu de fournir une référence à une fonction nommée, vous pouvez fournir une fonction anonyme pour un gestionnaire d'événements:
var myLink = document.getElementById ("myLink");
myLink.OnClick = function ()
{
alerte ("Engage!");
retourne false;
}
Selon que vous ayez besoin de réutiliser la fonction de traitement (et vos propres préférences de codage), cela peut être un moyen plus facile d'écrire du code de traitement des événements.
La valeur de retour de la fonction de traitement détermine si l'action par défaut pour cet événement se produit. Ainsi, dans le code précédent, si Mybutton était un hyperlien, son action par défaut lors du clic serait de naviguer vers son emplacement HREF. En renvoyant False, la fonction d'engagement ne permet pas que l'action par défaut se produise et la navigation sur l'hyperlien n'aura pas lieu. Si la valeur de retour était vraie, l'action par défaut se produirait après l'exécution du code de la fonction de traitement des événements.
Lorsqu'un événement se produit, des informations détaillées sur le comment, pourquoi et où cet événement est écrit dans un objet d'événement. Dans Internet Explorer, cela prend la forme d'un objet Global Window.Event, mais dans d'autres navigateurs, l'objet est passé comme un argument à la fonction de maniement des événements. Cette différence est assez facile à aborder dans la fonction de gestion:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
L'objet de l'événement vous permet de découvrir une gamme de détails, tels que l'élément cliqué, si des touches ont été enfoncées, les coordonnées de l'événement (par exemple, où le curseur a été localisé lorsque le bouton de la souris a été cliqué) et le type d'événement qui a déclenché la fonction. Un bon nombre des noms de propriétés de l'événement sont cohérents entre les navigateurs, mais quelques-uns diffèrent. Les propriétés de l'événement Mozilla peuvent être consultées à la référence Gecko Dom, tandis que les propriétés des événements Internet Explorer peuvent être vues sur MSDN. Pour les propriétés dont les noms varient entre les navigateurs, le potentiel de problèmes associés peut normalement être corrigé avec un peu de détection d'objets; Nous en discuterons en détail plus loin dans ce chapitre.
La voie W3C (auditeurs d'événements)
Bien que les gestionnaires d'événements DOM 0 soient rapides et faciles, ils ont des limitations (à part le fait qu'ils finiront par être dépréciés). Le principal avantage des auditeurs d'événements W3C est qu'ils soutiennent nativement l'addition et la suppression de plusieurs fonctions de manutention pour le même événement sur un seul élément. Les écouteurs d'événements ont également la capacité de répondre aux événements en plusieurs phases (bien que la plupart des navigateurs ne soutiennent pas encore cette capacité).
Dans la spécification W3C, un événement peut être ajouté à un élément utilisant la méthode AddEventListener de l'élément, mais Internet Explorer pour Windows choisit d'utiliser une méthode appelée attachévante, qui a une syntaxe légèrement différente. (Internet Explorer pour Mac ne prend en charge aucun de ces modèles d'événements, nous devons donc compter sur les gestionnaires DOM 0 pour travailler avec des événements dans ce navigateur.)
Pour ajouter un écouteur d'événements dans chaque navigateur, sauf Internet Explorer, vous écririez du code similaire à ceci:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Pour prendre en charge Internet Explorer, vous auriez besoin de ce code:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
ainsi que les noms de fonctions différents, il est important de noter qu'Internet Explorer utilise le nom du gestionnaire Dom 0 pour l'événement - "onClick" - plutôt que le vrai nom de l'événement: "cliquez". L'argument supplémentaire fourni à AddeveventListener spécifie si l'auditeur est appliqué pendant la phase de propagation de l'événement capture (vraie) ou bulle). La propagation des événements est expliquée plus en détail dans la discussion ci-dessous, mais la bulle est vraiment le choix le plus utile, et assure le même comportement dans les navigateurs conformes aux normes que dans Internet Explorer.
Les différences entre ces deux approches sont assez faciles à contourner en utilisant une fonction de résumé. Nous pouvons également fournir un repli aux navigateurs qui ne prennent pas en charge les auditeurs d'événements W3C en même temps:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Les deux premières déclarations IF traitent respectivement des méthodes basées sur les normes et de l'explorateur Internet, mais le cord-tout s'occupe des navigateurs plus âgés qui ne prennent en charge aucune de ces méthodes, en particulier Internet Explorer 5 pour Mac. Dans ce dernier cas, un gestionnaire d'événements DOM 0 est utilisé, mais pour s'assurer que plusieurs fonctions peuvent être utilisées pour gérer un seul événement pour un élément particulier, une fermeture est utilisée pour exécuter toutes les fonctions existantes qui sont attachées à l'événement.
Les fermetures sont une caractéristique avancée de JavaScript qui se rapporte à la portée (que vous pouvez lire dans le chapitre 19, orientation d'objet en JavaScript). Les fermetures permettent à une fonction intérieure de référencer les variables de la fonction de contenu même après la fin de la fonction de contenu. Simon Willison a expliqué leur utilisation en relation avec les gestionnaires d'événements en détail. Il suffit de dire que les fermetures nous permettent d'empiler plusieurs gestionnaires d'événements dans les navigateurs qui ne prennent pas en charge les auditeurs d'événements W3C.
Le code de navigateur croisé pour attribuer un écouteur d'événements est le suivant:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
pas (tout à fait) l'article authentique
Bien que le secours du gestionnaire d'événements DOM 0 imite la possibilité d'ajouter plusieurs écouteurs d'événements pour un type d'événement sur un élément, il ne fournit pas de réplication exacte du modèle d'événement W3C, car les gestionnaires spécifiques ne peuvent pas être supprimés d'un élément.
Alors que les gestionnaires DOM 0 ont permis l'annulation de l'action par défaut d'un élément en renvoyant False, les auditeurs d'événements W3C atteignent cet objectif légèrement différemment. Pour annuler une action par défaut dans ce modèle, nous devons modifier l'objet de l'événement. Internet Explorer vous oblige à définir sa propriété ReturnValue sur FAUX; Les implémentations basées sur les normes offrent la méthode de prévention pour faire la même chose. Nous pouvons créer une petite fonction qui comprend la différence pour nous:
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">
Nous pouvons appeler cette fonction chaque fois que nous voulons annuler l'action par défaut:
<div <br> onmouseover="changeBorder('red')" <br> onmouseout="changeBorder('black')">
Vous devez toujours renvoyer False après l'exécution de StopDefaultAction afin de vous assurer que les navigateurs qui ne prennent pas en charge le modèle d'événement W3C empêcheront également l'action par défaut.
Auditeurs d'événements Safari et W3C
En raison d'un bogue dans Safari, il est impossible d'annuler l'action par défaut de cliquer sur un hyperlien dans ce navigateur lors de l'utilisation d'écouteurs d'événements W3C. Pour réaliser l'annulation, vous devrez utiliser des gestionnaires d'événements DOM 0 avec une valeur de retour de false.
Vérification de la pièce jointe
Internet Explorer pour Windows transmet en fait un objet d'événement à la fonction d'événement lorsque PiyEvent est utilisé pour joindre un écouteur d'événements. Cependant, nous devons encore vérifier l'existence de cet objet pour tous les navigateurs qui utilisent l'ancien modèle d'événement.
L'un des avantages de l'utilisation des auditeurs d'événements W3C est que vous pouvez supprimer un écouteur individuel d'un élément sans déranger aucun autre auditeur sur le même événement. Ce n'est pas possible en utilisant les gestionnaires DOM 0.
Internet Explorer utilise la méthode Detachevent, tandis que les navigateurs conformes aux normes spécifient à la place une méthode appelée SupporEventListener. Chacune de ces méthodes fonctionne assez de manière similaire à son homologue d'ajout d'auditeur: un type d'événement doit être fourni avec la fonction qui a été affectée pour gérer ce type d'événement. La méthode standard demande également à savoir si le gestionnaire d'événements a été enregistré pour répondre pendant la phase de capture ou de bulle.
Voici une fonction qui prend en charge cette approche entre les navigateurs:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Le modèle d'événement W3C et les fonctions anonymes
Le modèle d'événement W3C ne permet pas la suppression des fonctions anonymes, donc si vous avez besoin de supprimer un écouteur d'événements, accrochez-vous à une référence à la fonction en question.
Dans les navigateurs qui ne prennent pas en charge les auditeurs d'événements W3C, cette fonction supprime tous les gestionnaires d'événements sur l'événement donné: il n'est pas possible de supprimer un seul d'entre eux et de laisser les autres.
Discussion
référençant l'élément cible
Très souvent, vous voudrez utiliser l'objet qui était la cible d'un événement à l'intérieur du gestionnaire d'événements lui-même. Avec les gestionnaires d'événements DOM 0, l'utilisation de la variable spéciale ceci à l'intérieur d'une fonction de traitement fera référence à l'objet cible de l'événement. Considérez ce code:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Ici, cela fait référence au lien avec id myLink. Nous pouvons l'utiliser pour obtenir l'attribut HREF du lien.
Cependant, si vous utilisez des auditeurs d'événements W3C, la cible de l'événement est stockée dans le cadre de l'objet de l'événement, sous différentes propriétés dans différents navigateurs. Internet Explorer stocke la cible comme Srcelement, tandis que le modèle de normes le stocke comme cible. Mais l'élément dans lequel ces propriétés pointent n'est pas nécessairement l'élément à laquelle l'écouteur d'événements a été attribué. C'est, en fait, l'élément le plus profond de la hiérarchie affectée par l'événement. Jetez un œil au HTML.
suivant<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Si un écouteur d'événements de clic était placé sur le paragraphe et qu'un utilisateur cliquait sur le lien, le gestionnaire d'événements de clic du paragraphe serait exécuté, mais l'objectif de l'événement qui était accessible via les propriétés susmentionnées serait l'hyperlien. Certains navigateurs (notamment, Safari) vont même jusqu'à compter le nœud de texte à l'intérieur du lien comme nœud cible.
Nous pouvons écrire une fonction qui renvoie l'objectif de l'événement, quelle que soit la propriété implémentée, mais cela ne résout pas le problème de la recherche de l'élément dans lequel nous avons initialement appliqué l'écouteur de l'événement. (La norme W3C spécifie une autre propriété appelée CurrentTarget, qui vous permet d'obtenir l'élément à laquelle l'auditeur a été affecté, mais il n'y a pas de équivalent Internet Explorer. Les navigateurs prennent en charge CurrentTarget a également mis en place le style de gestionnaire d'événements cette variable avec la même valeur, mais encore une fois, sans le support Internet Explorer, ce n'est pas particulièrement utile. Trouvez un élément susceptible d'être l'élément dans lequel nous avons joint un écouteur d'événements. Pour ce faire, nous pouvons effectuer des vérifications par rapport au nom de balise, à la classe et à d'autres attributs de l'élément.
La fonction cible de l'événement abstraite ressemblerait à ceci:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
L'IF-ELSE récupère la cible de l'événement à travers les navigateurs; La boucle while trouve alors le premier parent non-texte si la cible signalée par le navigateur se trouve être un nœud de texte.
Si nous voulons récupérer l'élément qui a été cliqué, nous passons alors un appel à GetEventTarget:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Parce que nous savons, dans ce cas, que la fonction de manutention de l'événement ne sera jointe qu'aux liens ( balises), nous pouvons itérer vers le haut à partir de la cible de l'événement, en vérifiant un nom de nœud de "A". Le premier que nous trouvons sera le lien auquel le gestionnaire a été attribué; Cela garantit que nous ne travaillons pas avec un élément à l'intérieur du lien (comme une forte ou une période).
Évidemment, cette méthode de recherche cible n'est pas idéale et ne peut pas être précise à 100% à moins que vous ayez une connaissance du HTML exact avec lequel vous travaillerez. Récemment, beaucoup d'efforts ont été consacrés à la résolution de ce problème, et pas mal des solutions proposées offrent la même variable que celles disponibles sous les gestionnaires d'événements DOM 0, et dans les navigateurs qui prennent en charge la norme W3C pour les auditeurs d'événements (pas Internet Explorer).
Une telle solution est de faire de la fonction d'écoute d'événements une méthode de l'objet cible dans Internet Explorer. Ensuite, lorsque la méthode est appelée, cela pointera naturellement vers l'objet pour lequel la méthode a été appelée. Cela nécessite à la fois la modification du PiTeventListener et de DetacheventListener:
<div <br> onmouseover="this.style.borderColor='red'" <br> onmouseout="this.style.borderColor='black'">
Cette ligne de pensée était bien représentée dans les entrées à la compétition Addvevent améliorée de Peter Paul Koch.
Une autre solution de Dean Edwards évite totalement le modèle d'événement W3C en faveur de la mise en œuvre des gestionnaires d'événements DOM 0 avec des capacités d'ajout et de suppression indépendantes.
Bien que ces deux solutions puissent s'avérer bien écrites et robustes, elles sont largement non testées au moment de la rédaction de cet article, nous nous en tiendrons donc à l'approche dont nous connaissons et pouvons gérer les défauts: celui présenté dans la solution principale. En outre, dans la pratique, le processus d'itération pour trouver la cible d'un événement n'est pas aussi peu fiable que possible.
Qu'est-ce que l'événement bouillonnant, et comment puis-je le contrôler?
Vous avez peut-être remarqué que nous devions fournir un troisième argument à la méthode W3C Standard AddeveventListener, et qu'un argument de capture a été inclus dans notre fonction attachEventListener pour répondre à cela. Cet argument détermine la phase du cycle d'événements dans lequel l'auditeur fonctionne.
Supposons que vous ayez deux éléments, l'un imbriqué à l'intérieur de l'autre:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Lorsqu'un utilisateur clique sur le lien, les événements de clic seront enregistrés à la fois sur le paragraphe et l'hyperlien. La question est de savoir laquelle reçoit l'événement en premier?
Le cycle de l'événement contient deux phases, et chacun répond à cette question d'une manière différente. Dans la phase de capture, les événements fonctionnent de l'extérieur, de sorte que le paragraphe recevrait d'abord le clic, puis l'hyperlien. Dans la phase de bulle, les événements fonctionnent de l'intérieur, de sorte que l'ancre recevrait le clic avant le paragraphe.
Internet Explorer et l'opéra ne prennent en charge que Bubbling, c'est pourquoi Pié-Piègne ne nécessite pas un troisième argument. Pour les navigateurs qui prennent en charge AddEventListener, si le troisième argument est vrai, l'événement sera capturé pendant la phase de capture; S'il est faux, l'événement sera capturé pendant la phase de bulle.
Dans les navigateurs qui prennent en charge les deux phases, la phase de capture se produit en premier et est toujours suivie de la phase de bulle. Il est possible qu'un événement soit géré sur le même élément dans les phases de capture et de bouillonnement, à condition de configurer des auditeurs pour chaque phase.
Ces phases mettent également en évidence le fait que les éléments imbriqués sont affectés par le même événement. Si vous ne voulez plus qu'un événement continue de se propager vers le haut ou vers le bas de la hiérarchie (selon la phase) après le déclenchement d'un auditeur d'événements, vous pouvez l'arrêter. Dans Internet Explorer, cela implique de définir la propriété CancelBubble de l'objet de l'événement à True; Dans le modèle W3C, vous devez plutôt appeler sa méthode stoppropagation:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Si nous ne voulions pas qu'un événement se propage plus loin que notre gestionnaire d'événements, nous utiliserions ce code:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Bien que nous ayons attribué la fonction d'engagement pour écouter l'événement de clic sur le lien et le paragraphe qui le contient, la fonction ne sera appelée qu'une fois par clic, car la propagation de l'événement est arrêtée par l'auditeur la première fois qu'il est appelé.
Il y a tellement de variables qui affectent la taille d'un élément - longueur de contenu, règles CSS, famille de polices, taille de police, hauteur de ligne, zoom de texte… la liste continue. Ajoutez à cela le fait que les navigateurs interprètent les dimensions CSS et les tailles de police de manière incohérente, et vous ne pouvez jamais prédire les dimensions auxquelles un élément sera rendu. Le seul moyen cohérent de déterminer la taille d'un élément est de le mesurer une fois qu'il a été rendu par le navigateur.
Solution
Vous pouvez dire immédiatement qu'il sera utile de savoir exactement quelle est la taille d'un élément. Eh bien, le W3C ne peut pas aider: il n'y a pas de moyen standardisé de déterminer la taille d'un élément. Heureusement, les fabricants de navigateurs ont plus ou moins réglé sur certaines propriétés DOM qui nous ont permis de le comprendre.
bien que les différences de modèle de boîte signifient qu'Internet Explorer inclut le rembourrage et les frontières de manière incohérente dans le cadre des dimensions CSS d'un élément, les propriétés offsetwidth et Offsetheight renverront systématiquement la largeur d'un élément - y compris le rembourrage et les frontières - dans tous les navigateurs.
Imaginons que les dimensions d'un élément ont été spécifiées dans CSS comme ceci:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Nous pouvons déterminer la largeur des pixels exacts de l'élément en JavaScript en vérifiant la largeur de décalage et les propriétés offensives correspondantes:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Dans Internet Explorer 6, Opera, Mozilla et Safari, la variable Pixelwidth sera désormais définie sur 450, et la variable PixelHeight sera définie sur 250. Dans Internet Explorer 5 / 5.5, Pixelwidth sera 350 et PixelHeight 150, car ce sont les dimensions dans lesquelles l'approche du modèle Broken Box utilisée dans ces éléments se fera des éléments. Les valeurs sont différentes entre les navigateurs, mais uniquement parce que la taille réelle rendu diffère également. Les dimensions de décalage calculent systématiquement les dimensions des pixels exacts de l'élément.
Si nous n'avons pas spécifié les dimensions de l'élément, et que nous avons plutôt laissé son affichage au rendu de bloc par défaut (en évitant ainsi les bogues du modèle de boîte), les valeurs seraient comparables entre les navigateurs (permettant des différences de largeur de barre de défilement, des polices, etc.).
Atteindre les dimensions correctes
Afin de déterminer correctement les dimensions d'un élément, vous devez attendre que le navigateur ait fini de rendre cet élément, sinon les dimensions peuvent être différentes de celles que l'utilisateur finit par voir. Il n'y a aucun moyen garanti de s'assurer qu'un navigateur a fini de rendre un élément, mais il est normalement sûr de supposer qu'une fois que l'événement de charge d'une fenêtre a été licencié, tous les éléments ont été rendus.
Discussion
Il est possible de récupérer les dimensions d'un élément moins ses frontières, mais y compris son rembourrage. Ces valeurs sont accessibles à l'aide des propriétés ClientWidth et ClientHeight, et pour l'exemple d'élément utilisé au-dessus de leurs valeurs serait de 300 et 100 dans Internet Explorer 5 / 5.5, et 400 et 200 dans tous les autres navigateurs.
Il n'y a pas de propriété qui vous permettra de récupérer la largeur d'un élément sans frontières ni rembourrage.
Connaître la position exacte d'un élément est très utile lorsque vous souhaitez positionner d'autres éléments par rapport à cela. Cependant, en raison de différentes tailles de navigateur, tailles de police et longueurs de contenu, il est souvent impossible de coder dur la position d'un élément avant de charger une page. JavaScript propose une méthode pour déterminer la position de tout élément après le rendu de la page, vous pouvez donc savoir exactement où se trouvent vos éléments.
Solution
Les propriétés OffsetTop et Offsetleft vous indiquent la distance entre le haut d'un élément et le haut de son parent offset. Mais qu'est-ce qui est offsent? Eh bien, cela varie considérablement pour différents éléments et différents navigateurs. Parfois, c'est l'élément contenant immédiat; D'autres fois, c'est l'élément HTML; À d'autres moments, c'est inexistant.
Heureusement, la solution consiste à suivre la piste des parents offset et à additionner leurs positions de décalage - une méthode qui vous donnera la position absolue précise de l'élément sur la page dans chaque navigateur.
Si l'élément en question n'a pas de préparant offsent, alors la position de décalage de l'élément lui-même est suffisant; Sinon, nous ajoutons les décalages de l'élément à ceux de son parent offset, puis répétons le processus pour son parent offsent (le cas échéant):
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
IE 5 pour Mac Bug
Internet Explorer 5 pour Mac ne prend pas compte de la marge ou du rembourrage du corps lors du calcul des dimensions de décalage, donc si vous désirez des mesures précises dans ce navigateur, vous devriez avoir des marges et un rembourrage zéro sur le corps.
Discussion
La méthode ci-dessus fonctionne pour des dispositions simples et complexes; Cependant, vous pouvez rencontrer des problèmes lorsqu'un ou plusieurs ancêtres d'un élément ont sa propriété de position CSS définie sur autre chose que statique (par défaut).
Il y a tellement de combinaisons possibles de positionnement imbriqué et de différences de navigateur qu'il est presque impossible d'écrire un script qui les prend tous en compte. Si vous travaillez avec une interface qui utilise beaucoup de positionnement relatif ou absolu, il est probablement plus facile d'expérimenter avec des cas spécifiques et d'écrire des fonctions spéciales pour les traiter. Voici quelques-unes des différences que vous pourriez rencontrer:
Lorsque vous travaillez avec des événements de souris, tels que Mouseover ou Mousemove, vous voudrez souvent utiliser les coordonnées du curseur de la souris dans le cadre de votre opération (par exemple, pour positionner un élément près de la souris). La solution expliquée ci-dessous est en fait une méthode de détection de localisation plus fiable que la méthode de détection de position de l'élément dont nous avons discuté dans la section appelée «trouver la position d'un élément», donc s'il est possible d'utiliser la solution suivante au lieu de la précédente, allez-y!
Solution
L'objet Event contient tout ce que vous devez savoir pour travailler avec la position du curseur, bien qu'un peu de détection d'objets soit nécessaire pour vous assurer d'obtenir des valeurs équivalentes sur tous les navigateurs.
La méthode standard d'obtention de la position du curseur par rapport à la page entière est via les propriétés Pagex et Pagey de l'objet de l'événement. Internet Explorer ne prend pas en charge ces propriétés, mais il comprend certaines propriétés qui sont presque celles que nous voulons. ClientX et Clienty sont disponibles dans Internet Explorer, bien qu'ils mesurent la distance du curseur de la souris aux bords de la fenêtre du navigateur. Afin de trouver la position du curseur par rapport à la page entière, nous devons ajouter la position de défilement actuelle à ces dimensions. Cette technique a été couverte dans le chapitre 7, en travaillant avec Windows et des cadres; Utilisons la fonction GetScrollingPosition de cette solution pour récupérer les dimensions requises:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Les info-bulleurs sont une fonctionnalité utile dans la plupart des navigateurs, mais elles peuvent être un peu restrictives si vous prévoyez de les utiliser comme parties de votre interface. Si vous souhaitez utiliser des calques qui apparaissent lorsque vous le souhaitez, ne sont pas tronqués et peuvent contenir plus que du texte brut, pourquoi ne pas faire vos propres info-bulleurs améliorés?
Solution
Pour cet exemple, nous appliquerons une classe, Hastooltip, sur tous les éléments pour lesquels nous aimerions apparaître des info-bulles. Nous obtiendrons les informations qui apparaîtront dans l'info-bulle de l'attribut de titre de chaque élément:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
De notre exploration des événements de navigateur plus tôt dans ce chapitre, vous aurez probablement déjà réalisé que nous devons configurer certains auditeurs d'événements pour nous faire savoir quand la couche devrait apparaître et disparaître.
Les info-bulleurs apparaissent classiquement dans un emplacement fixe lorsque vous souris sur un élément et disparaissez lorsque vous souris. Certaines implémentations des Intimes JavaScript déplacent également l'info-bulle lorsque la souris se déplace sur l'élément, mais je trouve personnellement cela ennuyeux. Dans cette solution, nous nous concentrerons sur les événements Mouseover et Mouseout:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>Nous avons déjà codé pas mal des fonctions de ce script, y compris AddloadListener du chapitre 1, en train de démarrer avec JavaScript, GetElementsByAttribute du chapitre 5, en naviguant sur le modèle d'objet de document et la fonction attachEventListener que nous avons créée plus tôt dans ce chapitre, donc le volume du code se trouve dans les fonctions d'écoute d'événements:
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>Après avoir obtenu un objet d'événement croisé et itérant de l'élément cible de l'événement de base à celui avec une classe de Hastooltip, Showtip se fait pour créer l'info-bulle (une div). Le contenu de l'info-bulle est tiré de l'attribut de titre de l'élément cible et placé dans un nœud de texte à l'intérieur de l'info-bulle.
Pour s'assurer que le navigateur n'affiche pas un info-bulle en plus de notre infraction améliorée, le titre de l'élément cible est ensuite effacé - maintenant, il n'y a rien à afficher pour le navigateur en tant qu'infiltre, donc il ne peut pas interférer avec celui que nous venons de créer. Ne vous inquiétez pas des problèmes d'accessibilité potentiels causés par la suppression du titre: nous le remettons plus tard.
Contrôle d'affichage de l'info-bulle dans l'opéra
L'opéra affiche toujours le titre d'origine même après l'avoir réglé sur une chaîne vide. Si vous souhaitez éviter que les info-bulleurs apparaissent dans ce navigateur, vous devrez arrêter l'action par défaut du Mouseover en utilisant la fonction StopDefaultAction de la section appelée «manipulation des événements», la première section de ce chapitre. Sachez que cela affectera également d'autres comportements de souris, tels que l'adresse d'adresse de la barre d'état pour les hyperliens.
Pour fournir des crochets pour le style de notre info-bulle, nous attribuons à l'élément Info-tools un ID basé sur l'ID de l'élément cible (TargetIdTooltip) et définissons une classe de chantier. Bien que cette approche permet d'appliquer les styles via CSS, nous ne pouvons pas calculer la position de l'info-bulle à l'avance, nous devons donc utiliser les coordonnées du curseur de la souris, comme calculé lorsque l'événement est déclenché, pour positionner l'info-bulle (avec quelques pixels supplémentaires pour lui donner de l'espace).Tout ce qui reste, c'est d'ajouter l'élément info-bulle au corps, il apparaîtra donc par magie lorsque nous souris sur le lien! Avec un peu de CSS, cela pourrait ressembler à la figure 13.1, «une couche générée dynamiquement qui apparaît sur Mouseover».
Figure 13.1. Une couche générée dynamiquement qui apparaît sur Mouseover
Lorsque la souris est déplacée de l'élément, nous supprimons l'influence du document, et elle disparaîtra:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Plus tôt, dans Showtip, nous avons créé une référence à l'élément Info-Tools en tant que propriété de l'élément cible. Après avoir fait cela, nous pouvons le supprimer ici sans avoir besoin de rechercher dans l'ensemble du DOM. Avant de supprimer l'info-bulle, nous récupérons son contenu et l'inservons dans le titre de l'élément cible, afin que nous puissions l'utiliser à nouveau plus tard.
ces objets existent-ils?
Vous devez vérifier que les objets créés dans d'autres auditeurs d'événements existent réellement avant d'essayer de les manipuler, car les événements peuvent souvent ramener, et vous ne pouvez pas garantir qu'ils se produiront dans un ordre défini.
Discussion
Un problème avec le code ci-dessus est que si l'élément cible est proche du bord droit ou inférieur de la fenêtre du navigateur, l'info-bulle sera coupée. Pour éviter cela, nous devons nous assurer qu'il y a suffisamment d'espace pour l'info-bulle et le positionner en conséquence.
En vérifiant, dans chaque dimension, que la position de la souris soit inférieure à la taille de la fenêtre du navigateur moins la taille de l'info-bulle, nous pouvons dire à quelle distance pour déplacer le calque afin de le mettre sur l'écran:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Cette fonction est identique à la version précédente jusqu'à ce que nous arrivions à l'insertion de l'élément d'info-bulle. Juste avant d'insérer l'élément, nous avons réglé sa visibilité à "cachée". Cela signifie que lorsqu'il est placé sur la page, le calque occupera le même espace qu'il prendrait s'il était visible, mais l'utilisateur ne le verra pas sur la page. Cela nous permet de mesurer les dimensions de l'info-bulle, puis de la repositionner sans que l'utilisateur ne le voit flasher dans sa position d'origine.
Afin de détecter si la couche s'affiche en dehors de la fenêtre, nous utilisons la position du curseur par rapport à la fenêtre. Cela pourrait théoriquement être obtenu en utilisant ClientX / Clienty, mais n'oubliez pas: Safari donne une valeur incorrecte pour cette propriété. Au lieu de cela, nous utilisons nos valeurs de navigateur croisé dans CursorPosition et soustrayons la position de défilement (qui est l'équivalent de ClientX / Clienty). La taille de la fenêtre est obtenue à l'aide de la fonction GetViewportSize que nous avons créée au chapitre 7, en travaillant avec Windows et des cadres, puis, pour chaque dimension, nous vérifions si la position du curseur plus la taille de la couche est supérieure à la taille de la fenêtre (moins une allocation pour les barres de défilement).
Si une partie de la couche va apparaître en dehors de la fenêtre, nous la positionnons en soustrayant ses dimensions de la taille de la fenêtre; Sinon, il est positionné normalement, en utilisant la position du curseur.
La seule autre exception à noter est que si la couche apparaissait normalement en dehors de la fenêtre dans les deux dimensions, lorsque nous la positionnons verticalement, elle est automatiquement positionnée au-dessus du curseur. Cela empêche la couche d'apparaître directement au-dessus du curseur et de déclencher un événement de souris. Il empêche également l'élément cible d'être totalement obscurci par l'info-bulle, ce qui empêcherait l'utilisateur de cliquer dessus.
Mesurer les dimensions de l'info-bulle visible
Pour que les dimensions de l'info-bulle soient mesurées, elles doivent d'abord être annexées au document. Cela le fera automatiquement apparaître sur la page, donc pour empêcher l'utilisateur de le voir afficher dans la mauvaise position, nous devons le masquer. Nous le faisons en définissant sa visibilité à "cachée" jusqu'à ce que nous ayons finalisé la position de l'info-bulle.
Nous ne pouvons pas utiliser la propriété d'affichage plus familière ici, car les objets avec affichage défini sur "aucun" ne sont pas du tout rendus, ils n'ont donc aucune dimension à mesurer.
peuvent être une mine d'informations, mais seulement si vous pouvez les comprendre correctement. Avoir la possibilité de trier une table par ses différentes colonnes permet aux utilisateurs de visualiser les données d'une manière qui leur a du sens et, finalement, offre une plus grande compréhension.
Solution
Pour commencer, nous utiliserons une table HTML sémantiquement significative. Cela nous fournira la structure dont nous avons besoin pour insérer des auditeurs d'événements, injecter des éléments supplémentaires et trier nos données:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Tout d'abord, nous devons configurer des auditeurs d'événements sur chacune de nos cellules d'en-tête de table. Ceux-ci écouteront les clics sur nos colonnes et déclenchent un tri sur la colonne qui a été cliquée:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
Internet Explorer 5 pour Mac a du mal à faire face au contenu de table généré dynamiquement, nous devons donc l'exclure spécifiquement de rendre l'une des tableaux triables.
Seules les tables avec la classe SortiableTable seront transformées en tables triables, donc iniTSortableTable navigue dans le DOM pour trouver les cellules de tête de table dans ces tableaux. Une fois qu'ils sont trouvés, le contenu de chaque cellule d'en-tête est enveloppé dans un lien hypertexte - cela permet aux utilisateurs de clavier de sélectionner une colonne pour trier la table par - et un écouteur d'événements est défini sur ces liens pour surveiller les événements de clic et exécuter SortColumn en réponse. L'attribut de titre de chaque lien est également défini, fournissant à l'utilisateur des informations sur ce qui se passera lorsque le lien est cliqué.
La fonction SortColumn est assez longue, en raison du fait qu'elle doit naviguer et réorganiser toute la structure de la table à chaque fois qu'une cellule de cap est cliquée:
<script type="text/javascript"> <br> function saySomething(message) <br> { <br> alert(message); <br> } <br> saySomething('Hello world!'); <br> </script>
Le premier pour la boucle qui se produit après toutes les variables structurelles a été définie définit les états respectifs pour chacune des cellules de cap de la table lorsque l'une d'elles est cliquée. Non seulement les classes sont maintenues pour identifier la cellule d'en-tête sur laquelle le tableau est actuellement trié, mais une propriété de SortOrder spéciale est maintenue sur chaque cellule pour déterminer l'ordre dans lequel cette colonne est triée. Initialement, une colonne sera triée par ordre décroissant, mais si une cellule d'en-tête est cliquée deux fois consécutivement, l'ordre de tri sera modifié pour refléter une séquence ascendante. Chaque cellule d'en-tête se souvient de l'état d'ordre de tri qu'il a présenté plus récemment, et la colonne est retournée à cet état lorsque sa cellule de cap est réélu. Le titre de l'hyperlien pour une cellule d'en-tête cliquée est également réécrit en fonction de l'ordre de tri actuel, et de l'ordre de tri si l'utilisateur cliquait dessus.
La seconde pour Loop trie chacune des lignes contenues dans le corps de la table. Une copie du TBOD d'origine est créée pour stocker les lignes de table réorganisées, et initialement cette copie est vide. Comme chaque ligne du TBOD d'origine est numérisée, le contenu de la cellule de table dans la colonne sur laquelle nous trions est comparé aux lignes déjà dans la copie.
Afin de trouver le contenu de la cellule de table, nous utilisons la fonction getinternaltext:
<ul > <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> <br> <script type="text/javascript" src="menu.js"></script>
<script type="text/javascript" src="menu.js"></script> <br> <br> <noscript> <br> <ul> <br> <li><a href="/">Home</a></li> <br> <li><a href="/about/">About</a></li> <br> <li><a href="/contact/">Contact</a></li> <br> </ul> <br> </noscript>
Lorsque SortColumn trouve une ligne dans la copie dont la valeur de cellule de table triée est «moins» que celle que nous scannons, nous insérons une copie de la ligne numérisée dans le TBOD copié. Pour une colonne dans l'ordre croissant, nous inversons simplement cette comparaison: la valeur de la ligne dans la copie doit être «plus grande» que celle de la ligne numérisée.
Cependant, avant une comparaison, nous vérifions si le contenu de la cellule de table triée peut être interprété comme un entier ou un flotteur; Si c'est le cas, les valeurs de comparaison sont converties. Cela garantit que les colonnes qui contiennent des nombres sont triées correctement; Les comparaisons de cordes produiront des résultats différents des comparaisons de nombres.
Une fois que toutes nos lignes originales ont été copiées dans le nouveau TBODY, cet élément est utilisé pour remplacer l'ancien, et nous avons notre table triée!
En utilisant les classes de triable et la triable, qui sont affectées aux cellules d'en-tête de table actuellement triées, nous pouvons utiliser CSS pour informer l'utilisateur de la colonne que la table est triée, et comment elle est triée, comme le montre la figure 13.2, "une table triable triée dans l'ordre descendant sur la quatrième colonne".
Figure 13.2. Une table triable triée en ordre décroissant sur la quatrième colonne
Figure 13.3. Une table triable triée par ordre croissant sur la deuxième colonne
Les deux principaux piliers du DHTML sont la capture des événements, et la réorganisation et la création d'éléments de page via le DOM. En utilisant ces principes, il est possible de capturer bon nombre des différentes façons dont les utilisateurs interagissent avec une page et que l'interface réponde en conséquence.
Comme le montre le nombre et la qualité des applications Web améliorées par JavaScript qui sont maintenant disponibles, les fonctionnalités que le DHTML peut apporter aux nouvelles interfaces représente l'un des plus grands domaines de croissance pour le JavaScript innovant. Les fondations et les exemples de base montrés dans ce chapitre vous donnent une idée de la puissance qu'il peut fournir dans le navigateur d'un utilisateur. Nous allons développer cela plus loin dans les chapitres suivants alors que nous construisons des interfaces vraiment intéressantes.
C'est tout pour notre échantillon de The JavaScript Anthology: 101 Conseils essentiels, astuces et hacks . Quelle est la prochaine étape?
Téléchargez cet échantillon comme un PDF, pour lire hors ligne. Découvrez la table des matières du livre pour voir ce qu'elle couvre d'autre. Et voyez ce que les autres pensent du livre - Lire les critiques des clients en direct de The JavaScript Anthology: 101 Conseils, astuces et hacks essentiels .
JavaScript est un composant crucial dans le développement Web. Il s'agit d'un langage de programmation qui vous permet d'implémenter des fonctionnalités complexes sur les pages Web. Lorsqu'une page Web va au-delà de la simple affichage d'informations statiques, telles que l'affichage des mises à jour de contenu en temps opportun, des cartes interactives, des graphiques animés ou du défilement de juke-box, JavaScript est impliqué. Il s'agit de la troisième couche du gâteau de couche des technologies Web standard, dont deux (HTML et CSS) que nous avons largement utilisées dans nos articles précédents.
Commencer à apprendre le javascript à partir de zéro peut sembler décontractée, mais c'est entièrement manageable si vous le rompez en étapes plus petites. Commencez par comprendre les bases du HTML et du CSS car ils forment le fondement du développement Web. Ensuite, vous pouvez progressivement passer à des bases JavaScript comme les variables, les types de données, les fonctions, les boucles et les conditions. La pratique est essentielle pour apprendre JavaScript, alors assurez-vous de coder régulièrement.
Certaines erreurs courantes commettent les débutants lors de l'apprentissage du javascript incluent la différence entre JavaScript et Java, ne pas dépenser suffisamment de temps à comprendre les bases et à ne pas pratiquer suffisamment. JavaScript est une langue unique avec ses propres concepts et structures, et il est important de les comprendre avant de passer à des sujets plus complexes. La pratique régulière et l'application des concepts apprises sont cruciaux pour maîtriser JavaScript.
Oui, vous pouvez apprendre JavaScript sans aucune expérience de programmation préalable. Bien que le fait d'avoir une formation en programmation puisse faciliter le processus d'apprentissage, ce n'est pas une condition préalable. JavaScript est souvent recommandé comme une bonne langue pour les débutants en raison de sa syntaxe indulgente et de sa large utilisation dans le développement Web.
Le temps nécessaire pour apprendre à apprendre et à l'idée de zéro peut varier en fonction de votre expérience antérieure, du temps que vous pouvez consacrer à l'apprentissage, et de la profondeur de la connaissance que vous souhaitez réaliser. En moyenne, si vous partez de zéro et que vous consacrez quelques heures par jour, vous pouvez vous attendre à apprendre les bases dans quelques semaines à quelques mois.
Il existe de nombreuses ressources disponibles pour apprendre le javascript. Des plateformes en ligne comme Codecademy, Udemy et FreeCodeCamp offrent des cours complets. Des livres comme "Eloquent Javascript" et "You Don't Know JS" sont également fortement recommandés. De plus, Mozilla Developer Network (MDN) a une documentation approfondie sur JavaScript.
Dans le développement frontal, JavaScript est utilisé pour rendre les pages Web dynamiques et interactives. Il peut être utilisé pour créer des fonctionnalités telles que les curseurs, former des validations, des fenêtres contextuelles, etc. Il vous permet également de manipuler le modèle d'objet de document (DOM), vous permettant de modifier le contenu et la mise en page d'une page Web en temps réel.
Oui, JavaScript peut être utilisé pour le développement arrière. Node.js est un runtime JavaScript qui vous permet d'exécuter JavaScript sur votre serveur. Avec Node.js, vous pouvez créer des applications Web entières en utilisant JavaScript.
Les frameworks et bibliothèques JavaScript sont-ils utiles? Ils fournissent une structure pour le code JavaScript, ce qui facilite la création d'applications Web à grande échelle, maintenable et évolutive. Les exemples incluent React.js, Angular.js et Vue.js.
JavaScript continue d'être une force dominante dans le développement Web et ses futurs semblent prometteurs. Avec la montée des cadres comme React, Angular et Vue, JavaScript devient plus puissant et polyvalent. De plus, le développement de Node.js a élargi la portée de JavaScript au côté serveur, ce qui en fait un langage complet. Alors que les applications Web continuent de croître en complexité, la demande de développeurs JavaScript qualifiés devrait rester élevée.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!