mercredi 14 novembre 2012

Tuto Js 2° partie

http://www.siteduzero.com/tutoriel-3-379719-manipuler-le-code-html-partie-1-2.html

On va entrer dans le vif du sujet. Après une fin de chapitre bien mais pas top (la solution donnée est meilleure que la mienne, faut dire ce qui est...) ben, je continue.
Nonmé, on m'aura pas comme ça !

DOM : API qui permet de faire communiquer les balises html et les éléments html. (balises js = éléments html).

on parle de DOM 1 lorsqu'on parle de l'arbre dont le parent principal est html, et qui a comme enfants principaux head et body. Il y a déjà eu à ce moment des modifs du W3C pour unifier le code.
Encore plus lorsqu'on parle du DOM 2, où l'élément getElementById() permet de récupérer un élément sans le situer, seulement par son id.

alert est une méthode qui appartient à l'objet window.
Ainsi, lorsqu'on écrit alert('truc');
on pourrait écrire window.alert('truc');

/!\ Une variable est en fait un élément de window. On peut y accéder comme ça :
alert(window.nom_de_variable);
Donc, quand on déclare des variables locales, on peut quand même appeler la globale par cet intermédiaire, même si on a renommé une locale par le nom de la globale. Moui, je sais, c'est nébuleux :
var blabla = 'blabla';
(function truc {
var blabla = 'blablabli';
alert(window.blabla); // affichera blabla, pas blablabli...
})();

Une chose importante encore :
si une variable n'est pas déclarée (var = ) eh bien elle est automatiquement un élément de window !
Donc, quand on donne une valeur à une variable, même au sein d'une fonction, elle est déclarée partout ailleurs. Faut donc faire gaffe à la portabilité des variables ! Bien déclarer une variable avec var à chaque fois, sinon bug assuré à l'arrivée !

document est un élément de window. Il définit la page html, grâce à lui, on peut naviguer dans la page.

On revoit les histoires de noeud, les arbres xml...
Pour accéder à un élément à l'aide de DOM, on a trois façons :
getElementById, getElementsByTagName (!! s à elements), ou encore getElementByName

getElementById permet de récupérer par id un élément, donc.
Par exemple, on a un div dans la page dont l'id est "truc", on peut y accéder comme suit :
divtruc = document.getElementById('truc');
-> Cela permet de changer le contenu, par exemple...

getElementsByTagName est intéressant mais très différent.
Il permet de récupérer sous forme de tableau tous les éléments de la famille. Par exemple :
divs = document.getElementsByTagName('div');
-> Enregistre tous les éléments div dans le tableau divs.
Pour y accéder ultérieurement, on parcourra son contenu à l'aide d'une boucle (cf vu plus haut dans le cours)
for(var i=0, c = divs.length; a < c; c++)
{ alert('Elément ' + (i +1)  +  ': ' + divs[i] + '\n') ;
}

Cette méthode est accessible sur n'importe quel élément html, pâs forcément seulement document.
Astuce importante : Avec une * en paramètre, on peut récupérer tous les éléments enfants de l'élément ciblé. (pas sûre d'avoir compris.)

getElementByName est sensiblement pareille que ByTag. Je retiens surtout qu'elle est décriée en xHTML, quoi que standardisée en html5.

On a aussi des méthodes apparues dernièrement et pas très très compatibles avec tous les navigateurs.
Aussi, à utiliser avec parcimonie.
Exemple : querySelector , querySelectorAll .

On va voir ça avec l'exemple d'une page html basique.
htmlbody
div id="main"
div class="menu"
span
1 texte ici, juste du texte
 .span
span
2 texte aussi
.span
.div
div class="pasmain"
span
autre texte
.span
.div
.div
.body
.html

(j'ôte les balises pour problèmes de compatibilité avec le blog, c'est relou.)
Donc, en gros, si je fais :
var query = document.querySelector('#main .menu span');
je devrais accéder au premier contenu : 1 texte ici, juste du texte
alert('query.innerHTML');

Si je fais var querys = document.querySelectorAll('#main .menu span');
là, j'ai un tableau qui aura enregistré tout le contenu. (parcourir à l'aide d'une boucle...)

A l'heure actuelle, avec parcimonie, mais ça sera général d'ici peu.
---------------------------------------------------------------------------------

Tous les éléments html sont du même type : node (noeud).
Mais attention, ça ne signifie pas que ce soient les mêmes objets !
Ainsi, l'élément div est un objet HTMLDivElement , qui appartient à HTMLElement, lui-même Element dans Node. :s
L'objet Node apporte son lot de méthodes (héritage) que l'on pourra utiliser dans les autres objets enfants.
Youpi !

----------------------------------------------------------------------------------------------------------------

Les éléments html sont souvent composés d'attributs.
Exemple, a a comme attribut href, et comme contenu #text . Mais le contenu peut également être un élément html... (comme dans a href='adresse.url' img src='adresse.jpg'. .a )

L'objet Element nous offre deux façons d'intéragir avec l'attribut :
getAttribute() et setAttribute() : get récupère, set édite. L'argument à passer est le nom de l'attribut, et dans le cas de set, le nouveau contenu à assigner.
exemple :
a id='monlink' href='lienfictif1.html' blabla .a
link = getElementById('monlink');
href = link.getAttribute('href');// on récupère l'attribut href

link.setAttribute('href', 'www.nouveaulien.htm'); // on assigne à l'att href une nouvelle valeur.

... autre méthode :
On peut souvent accéder à des propriétés par l'intermédiaire des objets.
Par exemple, pour l'ex du dessus :
var link = getElementById('monlink');
var href = link.href;

Si on veut la modifier, y a qu'à redéclarer !
link.href = ('lienmodifié.htm');

-> C'est ça qu'on utilise majoritairement pour modifier les formulaires. Bon, ça, je savais...

On pourrait croire que pour modifier l'élément "class" d'un objet il suffit d'utiliser class, mais le mot est réservé en js. Il faut employer className :
de la même façon, l'attribut for de label...
for est réservé pour les boucles, on ne peut y faire appel que par : htmlFor
document.htmlFor accède à l'attribut for, donc.
J'apprends qu'on peuit déclarer plusieurs classes à un objet. Du coup, pour récupérer plusieurs classes, si on récupère par var classe = document.getElementById('idenquestion').className;
on récupère une string avec des espaces qu'il faudra splitter.
hum. Nébuleux.

Propriété innerHTML

innerHTML est supporté par tous les navigateurs, et vient donc d'être standardisé, mais c'est récent.
On peut donc l'employer sans souci.
Ca permet d'assigner une valeur, de la récupérer, de la manipuler, quoi...
On peut également ajouter à l'aide de l'opérateur +. Voici trois exemples d'utilisation d'innerHTML :


var phrase = document.getElementById('divenquestion').innerHTML;
alert(phrase); // écrit le contenu de ce qui est dans les balises divenquestion
donc après, pour changer cette valeur, suffit de lui assiogner une nouvelle valeur...
document.getElementById('divenquestion').innerHTML = 'nouvelle valeur';
alert(phrase); // affiche 'nouvelle valeur'
document.getElementById('divenquestion').innerHTML += ' encore';
alert(phrase); // affiche "nouvelle valeur encore"
Attention à ne pas trop en user, de la concaténation, parce que ça ralentit. Si on veut ajouter des bouts et encore, vaut mieux faire d'abord le calcul puis ajouter le tout à la fin.

On ne peut pas créer une balise script par le biais de la propriété innerHTML. On le peut, mais grâce à createElement.
Wooow ! Quel chapitre passionnant !!

--------------------------------------------------------------------------------------------------

Maintenant, innerText et textContent
: innerText est supporté par microsoft (IE) là où textContent l'est chez les autres.
pas standardisé, donc.

L'avantage, c'est qu'on récupère à l'aide de cette méthode le contenu sans les balises.
textContent est la soeur jumelle, non supportée par IE à l'exception du 9.
astuce : pour l'utiliser, on peut faire une petite boucle if. Si elle marche, c'est cool, sinon c'est pas le bon nav :
var div = document.getElementById('mydiv');
var txt = '';
if(div.innerText) {
txt = div.innerText;
} else if (div.textContent) {
txt = div.textContent;
} else {
txt = '';
}
// On enregistre le contenu selon que l'une ou l'autre des méthodes fonctionne, sinon, on enregistre une variable vide.

On peut faire ça super simplement, évidemment :
txt = div.textContent || div.innerText || '';
ben oui, puisque la première condition vérifiée sera enregistrée... 
 
element.className et element.getAttribute("class") sont strictement équivalents
 
  • Question
    Comment récupérer le contenu textuel d'un élément HTML ?
    -> textContent
    attention, j'ai répondu innerHTML, qui récupère le contenu textuel + balises.
    textContent, j'ai pas répondu ça parce que c'est pas uniformisé, mais j'm'ai gouré. 
 Ok, révision le lendemain, c'était nécessaire.
A noter : innerHTML donne le texte avec les balises.
contentText ou innerText donnent le texte SANS balises, c'est super pratique à connaître.
 
Exercice effectué sur une page du site du zéro enregsitrée en html (source...)
        var querys = document.querySelectorAll('#speedConnection li');

        for(var a=0, i=querys.length; a++)
{
                       alert(querys[a].innerText || querys[a].textContent || 'error'); 
} // cette ligne affiche le contenu sans balises, ou error, selon le navigateur.

Aucun commentaire:

Membres