Certaines propriétés restent inchangeables

Mammouth du PHP | 881 Messages

22 avr. 2011, 09:34

Bonjour,

ouf, il y a bien longtemps que je sois venu ici! Au nombre de messages, le site semble en bonne santé. J'espère que c'est le cas pour vous aussi.

Je suis à monter un plugin Joomla. Je veux un effet "fondu" pour passer d'une image "background" à l'autre. La solution que j'ai trouvée est prometteuse, mais je me bute à ceci: certaines propriétés des div restent inchangeables alors que d'autres changent bien et prouvent que je pointe vers les bons éléments.

Voici mon code:

Code : Tout sélectionner

<script> //Duplication de la div contenant l'image à changer, en vue du fondu Epais = 100; Orig_Width = document.getElementById('Header').offsetWidth; Orig_Height = document.getElementById('Header').offsetHeight; Orig_Left = document.getElementById('Header').offsetLeft; Orig_Top = document.getElementById('Header').offsetTop; document.write('<div id="Duplicata_div_ChgHeaderOnLoad" style="position: absolute; opacity: 1; visibility:visible; z-index: 1; top: ' + Orig_Top + 'px; left: ' + Orig_Left + 'px; height: ' + Orig_Height + 'px; width: ' + Orig_Width + 'px; background: url(\'images/header/header.jpg\') repeat; " >'); document.write('</div>'); document.getElementById('Header').style.zIndex = 0; var MesPetits = document.getElementById('Header').childNodes; for(i=0;i<MesPetits.length;i++) { if (MesPetits[i].id != '' && MesPetits[i].id != undefined) { document.getElementById(MesPetits[i].id).style.zIndex = Epais++; alert("Voici une banane: " + MesPetits[i].id + "\nOui, mais encore: " + document.getElementById(MesPetits[i].id).style.zIndex ); } } </script>
Je crée une div qui devrait se glisser entre la div mère et ses div filles. Peut-être est-ce là mon problème ?!?!?

Dans mon code, je ne vois aucun effet à des changements aux div filles lorsque je commande des .style.top .style.left
Cependant, si je demande un .style.visibility = "hidden" pour ces mêmes div filles ... alors là! Pop ... il n'y en a plus!
C'est donc dire que je pointe sur les bonnes div et de la bonne manière.
Alors pourquoi top, left, zIndex n'ont aucun effet ?
Comment faire en sorte que ces commandes aient de l'effet sur mes div ?

Au fait, j'ai aussi tenté d'apporter ces modifs après avoir éliminé toutes traces de la div créée. Ce n'est pas mieux.

Mes messages commençant par "Voici une banane" me donnent pourtant les résultats d'un modification apportée.
Je fais appel à votre expérience de long temps perdu pour une virgule, ou votre logique implacable.

Merci à l'avance.
Soyez artisans de paix

devlop78
Invité n'ayant pas de compte PHPfrance

23 avr. 2011, 03:54

Je n'ai pas tout lu, mais ce qui ne va pas, dès le départ, c'est le code.

Déjà, utiliser un framework JS serait mieux, mais ça, c'est un choix.

Ce qui me choque, c'est le document.write() pour écrire un DIV. Là c'est vraiment ... très très mal. A l'extrême, un body.innerHTML += '' passerait, mais là ... Surtout, ne JAMAIS couper un innerHTML par exemple comme tu l'as fait. Si tu ouvres DIV, tu dois le fermer dans le même temps, et pas une ligne en dessous, sinon, soit il ignore les deux, soit il te ferme la première lui-même et ignores la fermeture, ou alors il fait davantage de bizarreries.

Ne pas oublier que JavaScript intervient ici sur le DOM. Autant donc le manipuler comme il faut, c'est à dire que c'est une montagne d'éléments (objets) liés entre eux par une hierarchie. Ca semble un peu bateau ce que je dis, mais j'espère que l'image peut aider. C'est une sorte d'arbre généalogique.

Donc, tu lui dis :

- var enfant = nouveau Element DIV;
- enfant.attribut_y = ...
- maman.ajoute(enfant)

Pour reprendre http://fr.selfhtml.org/javascript/objets/document.htm :

Code : Tout sélectionner

var montitre = document.createElement("h1"); var montexte = document.createTextNode("Une page très dynamique"); montitre.appendChild(montexte); var passagesortie = document.getElementById("passage"); passagesortie.appendChild(montitre);
Voilà ;)

Mammouth du PHP | 881 Messages

23 avr. 2011, 09:07

Merci grandement, j'ai l'impression que ça progresse.
Voici mon nouveau code

Code : Tout sélectionner

//Duplication de la div contenant l'image à changer, en vue du fondu Epais = 100; var LesAttributs = new Array(); var LaNouvDiv = document.createElement("div"); var MesPetits = document.getElementById('Header').childNodes; //Traitement des sous-div existantes, pour s'assurer qu'elles restent au-dessus de la nouvelle div for(i=0;i<MesPetits.length;i++) { if (MesPetits[i].id != '' && MesPetits[i].id != undefined) { //Ici j'ai essayé d'appliquer la méthode que vous me suggérez, sans succès. // var PropDiv = document.createAttribute("z-index"); // PropDiv.nodeValue = Epais++; // MesPetits[i].setAttributeNode(PropDiv); //Méthode précédente document.getElementById(MesPetits[i].id).style.zIndex = Epais++; alert("Voici une banane: " + MesPetits[i].id + "\nOui, mais encore: " + document.getElementById(MesPetits[i].id).style.zIndex ); } } //Attributs de la nouvelle div LesAttributs[0] = Array ("id", "Duplicata_div_ChgHeaderOnLoad"); LesAttributs[1] = Array ("position", "absolute"); LesAttributs[2] = Array ("opacity", 1); LesAttributs[3] = Array ("z-index", 200); LesAttributs[4] = Array ("top", document.getElementById('Header').offsetTop); LesAttributs[5] = Array ("left", document.getElementById('Header').offsetLeft); LesAttributs[6] = Array ("height", document.getElementById('Header').offsetHeight); LesAttributs[7] = Array ("width", document.getElementById('Header').offsetWidth); LesAttributs[8] = Array ("background", "url(\'images/header/header.jpg\') repeat;"); LesAttributs[9] = Array ("visibility", "visible"); for (x=0; x<LesAttributs.length; x++) { var PropDiv = document.createAttribute(LesAttributs[x][0]); PropDiv.nodeValue = LesAttributs[x][1]; LaNouvDiv.setAttributeNode(PropDiv); } //Insértion dans la page var PrecDiv = document.getElementById("Header"); PrecDiv.appendChild(LaNouvDiv); var PropDiv = document.createAttribute("z-index"); PropDiv.nodeValue = 0; PrecDiv.setAttributeNode(PropDiv);
Ma nouvelle div n'est pas visible.
Il ne semble pas y avoir de faute de frappe, car le message d'alert apparaît bien.

Je suis sûr que la nouvelle div est créée, car j'ai dû déplacer le bloc de "traitement des div existantes" sans quoi ma nouvelle div passait à cette moulinette aussi.

J'apprends beaucoup ici, merci déjà pour ça.
Soyez artisans de paix

Mammouth du PHP | 881 Messages

23 avr. 2011, 09:14

Je crois que j'ai une piste.

Plutôt que de créer une nouvelle <div>, je m'essaie maintenant à créer une nouvelle <img>

Je vous en donnerai des nouvelles.
Soyez artisans de paix

Mammouth du PHP | 881 Messages

23 avr. 2011, 09:22

Sans succès, l'image n'accepte d'être en-dessous. Pour cela, il faut vraiment qu'elle soit utilisée en "background".
Fallait essayer!
Soyez artisans de paix

Mammouth du PHP | 881 Messages

23 avr. 2011, 09:44

Pour être plus précis,

mes expériences ci-haut m'ont permis de vérifier que le code de de Patriboom le 23 Avr 2011, 04:07 (long message) donne bien une div aux dimensions et position voulues. Cependant, cette div se trouve encore et toujours sous sa mère, même avec un z-index de 200 alors que la mère a 0.
Soyez artisans de paix

devlop78
Invité n'ayant pas de compte PHPfrance

24 avr. 2011, 04:10

Là comme ça, je ne peux pas te dire. Il faudrait télécharger Firefox Firebug, qui te permettra d'afficher toutes les erreurs JavaScript (mais ça firefox peut déjà le faire), mais aussi d'inspecter ton DOM en temps réel.

Quelques remarques :

if (MesPetits.id != '' && MesPetits.id != undefined)

mieux vaut

if (MesPetits.id != undefined && undefinedMesPetits.id != '')

Ensuite, "position" n'est pas un attribut, mais un style CSS.

Ensuite, "PropDiv.nodeValue = 0;" n'est pas nécessaire.

Passe moi l'url de ta page, je jetterai un coup d'oeil si tu veux, là je ne vois rien. Ensuite, je te conseille toujours un framework, le début n'est pas toujours facile, mais quand tu as compris le principe d'un truc et que tu as les bases syntaxicales de JS, c'est un vrai bonheur et tu vas beaucoup plus vite (sans parler que tu n'as presque plus besoin de faire de dissociation des navigateurs).

devlop78
Invité n'ayant pas de compte PHPfrance

24 avr. 2011, 04:13

Autre chose : apparemment, javascript est capable d'utiliser les variables non déclarée. Néanmoins, à chaque fois que j'ai voulu les utiliser j'ai eu des erreurs ^^ et puis ... il y a une différence de portée.

Donc, quelque soit le langages, je te conseille de la déclarer avec le mot clé var.

Mammouth du PHP | 881 Messages

24 avr. 2011, 04:33

Merci develop78,

ce que j'essaie de faire, c'est améliorer un petit plugin que j'ai fait pour Joomla (donc, oui, j'ai un framework). Le plugin est disponible sur mon site : http://www.cartefoi.net/compl_compl_2.php#Informatique ou encore sur http://extensions.joomla.fr Il s'agit simplement d'un slideshow en arrière plan pour l'en-tête. Les questions que j'apporte ici sont pour compléter ce plugin afin que les images ne fassent pas seulement que passer, mais aussi le fassent bellement (fusion, pour l'instant, on verra d'autres styles plus tard). Le défi vient du fait que le plugins ne pouvait être installé que dans les plugins "system" de Joomla, ceux qui sont lus avant la balise <body>, avant les paramètres personnalisés par le template. La partie que j'apporte ici doit évidemment être lue après la balise body. Oui, j'ai essayé de faire chose semblable dans la première portion de mon plugin mais ça n'affiche strictement rien, car ça crée une <div> avant <body> donc html ne sait pas quoi faire avec.

Quant à l'adresse où trouver cela: c'est en développement local seulement pour l'instant. Ce que je fais, pour simplifier, j'ai le-dit code inséré directement dans mon fichier index.php du template en cours d'utilisation. L'autre partie du plugin est - bien entendu - déjà enregistrée à part en tant que plugin dans ../plugins/system/ChgHeader.. comme Joomla 1.6 sait très bien le classer.

Merci pour les conseils et le support, :) je n'avais jamais avancé autant en javascript depuis le temps où je me suis mis à changer quelques scripts pigés à gauche et à droite pour faire des petites animations (il y a 15 ans!). :wink:
Soyez artisans de paix

devlop78
Invité n'ayant pas de compte PHPfrance

24 avr. 2011, 05:15

Tout simplement dire au code javascript de ne se lancer que quand le DOM est chargé, ce qui se fait les doigts dans le nez avec un framework js.

quelque chose comme :

document.load = function () {

// Le code

}

Mammouth du PHP | 881 Messages

24 avr. 2011, 07:41

Wow!

on m'a enseigné, quand j'étais petit, de ne pas me mettre les doigts dans le nez, mais là, décidément, il faut que j'essaie ça!

Merci.

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


Quelques minutes après. Mon nez est propre!

Sérieux, j'ai trouvé ceci:

Code : Tout sélectionner

var head, ref; head = document.getElementsByTagName('head')[0]; if (!head) { return; } script = document.createElement('script'); script.type = 'text/javascript'; script.src = js; script.addEventListener( "load", onload, false ); head.appendChild(script); }
là: http://fr.w3support.net/index.php?db=so&id=19035

La chose me semble logique est compréhensible, mais le gars n'a pas l'air sûr. Aussi, il est question de charger un fichier js (dans le texte entourant le code cité) Je ne veux pas charger un fichier .js (car j'ai lu createDocument en lieu et place de create Elements), je veux simplement ajouter quelques commandes, voire une fonction en fin de chargement.

Première question: je trouve étonnant qu'on ajouter la fonction au "head", ne serait-il pas plus pertinent d'ajouter à <body> ?
Deuxième question: la fonction que je veux ajouter est autrement plus compliquée, avec des variables et des trucs par ci, des trucs par là. Comment faire pour ajouter cela à mon objet? Il me semble que je ne serai pas plus avancé qu'avec mon vieux document.write et ses \' \" pour pallier à la multiplication des insértions! Est-ce que je ne pourrais pas tout fourrer dans une fonction et juste faire ajouter ma fonction à body ou head (voir première question) ?

Merci encore.
Soyez artisans de paix

Mammouth du PHP | 881 Messages

24 avr. 2011, 08:31

Et puis ... après vérification, même la création de <head> vient après le chargement de code.
Il faut vraiment que je trouve comment faire ce que tu me proposes, soit différer le traitement javascript à la fin du chargement du document. La piste que tu me donnes m'est difficile à suivre ou - du moins - il m'est difficile de trouver des exemples ou des détails pour une telle commande. Saurais-tu me donner plus pour que je trouve plus aisément? Merci.
Soyez artisans de paix

devlop78
Invité n'ayant pas de compte PHPfrance

24 avr. 2011, 15:20

Non ... Je sais pas ce que c'est tout ça, mais on va pas créer dynamiquement un code JS.

Il faut comprendre le principe de HTML, DOM et JS. HTML te construit une multitude de noeuds dans le DOM dans "document". Mais le navigateur lit la page de haut en bas, excepté pour les images et d'autres mais qu'importent les détails. Bref, si tu affiches un <h1> et que tu mets un code JS puis un <h2>, tu verras un h1, le code s'executera, puis seulement après un h2. Le h2 ne s'est pas encore chargé lorsque le script se lance.

Je pense que le navigateur attend le chargement intégral du code HTML, car pour le parsage c'est obligatoire. Mais l'ensemble a été conçu pour réagir comme ça. Ainsi, il faut attendre que l'ensemble du DOM soit chargé pour intervenir efficacement dessus, notamment sur les éléments qui sont chargés après l'execution du script.

Parallèlement, javascript possède pas mal d'évenement qui "écoutent" le DOM. Parmi ces évenements, il y en a un qui se déclenche après le chargement du DOM, et un autre après le chargement intégral de la page. Attention que là dessus, je ne suis pas sûr, mais le DOM est chargé lors de leurs appels, ça c'est sûr.

Ainsi, ton document ressemble à:

Code : Tout sélectionner

<html> <head> <script> document.onload = function () { // Ici sera le code à executer après chargement du DOM } </script> </head> <body> <h1></h1> </body> </html>
Il te faut te renseigner sur la syntaxe exacte. Tu peux ajouter explicitement un écouteur (comme tu l'as fait avec addEventListener), mais aussi implicitement avec le .load et .onload. La grosse difficulté de ces trucs là c'est tout simplement la différence de syntaxe avec les navigateurs. Et c'est là que les gentils frameworks nous sauvent la vie ;)

Exemple avec JQuery :
<script>
$(function () {

$("h1").text ('Bonjour");

});
</script>
Ici, on enregistre une fonction anonyme qui sera lancé dès le DOM prêt. C'est jQuery qui se charge de ça.
Ensuite, tu dis de chercher les h1 et de mettre à l'intérieur le texte Bonjour. Ce texte est échappé, dans tu peux y mettre des balises, ça les affichera tel quel à l'écran du navigateur. En plus, tu n'as pas à te soucier de comment JQuery se charge de mettre ce texte (innerHTML, création d'un textnode, etc). En tous cas, il le fait très bien ^^.

Donc ensuite, facile de continuer. Attention que jQuery possède un fort polymorphisme, qui fait qu'il est capable de faire beaucoup de chose avec la même fonction : $ ou jQuery.
var monDivPapa = $("#header");
var monNouveauDiv = $("<div></div");
monNouveauDiv.attr('id','MonIdentifiant').css({'z-index':'100','opacity':'0'});
monDivPapa.append(monNouveauDiv);
monNouveuDiv.fadeIn(1000);
Voilà ... Ici je récupère un objet Jquery qui pointe vers mon header. Je crée un nouveau DIV, je lui donne un identifiant, un zindex, et je le cache. Ensuite, je le rajoute à son père, et je lui dis de se montrer progressivement sur 1 seconde.

Petite précision : utiliser une boucle de type for() pour augmenter l'opacité n'a aucun interêt. Visuellement, tu ne verras rien, et cela bloque le script sur la boucle. jQuery utilise des timers pour ça, donc en gros, des fonctions lancées à intervalles régulières.

A+

Mammouth du PHP | 881 Messages

25 avr. 2011, 03:41

Encore bien du temps investi, toujours pas le résutlat escompté.

Voici que je me rends compte que mes propriétés ne sont pas lues / pas appliquées. Le petit test que voici le prouve:

Code : Tout sélectionner

//Attributs de la nouvelle div LesAttributs[0] = Array ("id", "Duplicata_div_ChgHeaderOnLoad"); LesAttributs[1] = Array ("position", "absolute"); LesAttributs[2] = Array ("opacity", 1); LesAttributs[3] = Array ("top", document.getElementById('Header').offsetTop); LesAttributs[4] = Array ("left", document.getElementById('Header').offsetLeft); LesAttributs[5] = Array ("height", document.getElementById('Header').offsetHeight); LesAttributs[6] = Array ("width", document.getElementById('Header').offsetWidth); LesAttributs[7] = Array ("background", "url(\'images/header/header.jpg\') repeat;"); LesAttributs[8] = Array ("visibility", "visible"); //LesAttributs[9] = Array ("z-index", 1); for (x=0; x<LesAttributs.length; x++) { var PropDiv = document.createAttribute(LesAttributs[x][0]); PropDiv.nodeValue = LesAttributs[x][1]; LaNouvDiv.setAttributeNode(PropDiv); } //Insértion dans la page var PrecDiv = document.getElementById('Header'); PrecDiv.appendChild(LaNouvDiv); alert("Voici son ID : " + document.getElementById('Duplicata_div_ChgHeaderOnLoad').id); //réponse: Duplicata_div_ChgHeaderOnLoad -> C'est très bien alert("Voici sa position : " + document.getElementById('Duplicata_div_ChgHeaderOnLoad').position); // réponse: function(h) {return this.setStyles(this.Position(h))} -> Qu'est-ce que ça veut dire? alert("Voici sa valeur top : " + document.getElementById('Duplicata_div_ChgHeaderOnLoad').style.top); réponse: (aucune) alert("Voici son style.zIndex : " + document.getElementById('Duplicata_div_ChgHeaderOnLoad').style.zIndex); réponse: (aucune) alert("Voici son zIndex : " + document.getElementById('Duplicata_div_ChgHeaderOnLoad').zIndex); réponse: undefined
J'ai essayé le même système, mais sans boucle d'application; j'ai essayé de coder les propriétés en dur, mais rien n'y fait.

Des suggestions?
Soyez artisans de paix

Mammouth du PHP | 881 Messages

25 avr. 2011, 04:20

Avec ce que j'avais avant (voir ci-haut), les propriétés n'étaient pas prises en compte pour la nouvelle div, aucune sauf id. Ça faisait en sorte que ma div se trouvait "en-dessous" de la div à laquelle elle était attachée en tant que fille.

Avec ceci, les propriétés sont prises en compte, sauf zIndex:

Code : Tout sélectionner

<script> //Duplication de la div contenant l'image à changer, en vue du fondu var Epais = 44; var LesAttributs = new Array(); var LaNouvDiv = document.createElement("div"); var MesPetits = document.getElementById(id).childNodes; //Identification de la nouvelle Div var PropDiv = document.createAttribute("id"); PropDiv.nodeValue = "Duplicata_div_ChgHeaderOnLoad"; LaNouvDiv.setAttributeNode(PropDiv); //Insértion dans la page var PrecDiv = document.getElementById(id); PrecDiv.appendChild(LaNouvDiv); LaNouvDiv = document.getElementById('Duplicata_div_ChgHeaderOnLoad'); document.getElementById(id).style.zIndex = 1; //Attributs de la nouvelle div document.getElementById('Duplicata_div_ChgHeaderOnLoad').style.position = "absolute"; document.getElementById('Duplicata_div_ChgHeaderOnLoad').style.top = document.getElementById(id).offsetTop; document.getElementById('Duplicata_div_ChgHeaderOnLoad').style.left = document.getElementById(id).offsetLeft; document.getElementById('Duplicata_div_ChgHeaderOnLoad').style.height = document.getElementById(id).offsetHeight; document.getElementById('Duplicata_div_ChgHeaderOnLoad').style.width = document.getElementById(id).offsetWidth; document.getElementById('Duplicata_div_ChgHeaderOnLoad').style.background = "url: 'images/header/header.jpg' repeat"; document.getElementById('Duplicata_div_ChgHeaderOnLoad').style.opacity = 1; document.getElementById('Duplicata_div_ChgHeaderOnLoad').style.visibility = "visible"; document.getElementById('Duplicata_div_ChgHeaderOnLoad').style.zIndex = Epais++; for(i=0;i<MesPetits.length;i++) { if (MesPetits[i].id != '' && MesPetits[i].id != undefined && MesPetits[i].id != PropDiv.nodeValue) { document.getElementById(MesPetits[i].id).style.zIndex = Epais++; } } alert ("Voici la valeur utilisée: " + document.getElementById('logo').style.zIndex); alert ("Voici la valeur utilisée: " + document.getElementById('topmenu').style.zIndex); document.getElementById('logo').style.zIndex = Epais++; document.getElementById('topmenu').style.zIndex = Epais++; </script>
C'est précisément sur z-Index que je veux travailler.
Soyez artisans de paix