Partage
  • Partager sur Facebook
  • Partager sur Twitter

[JS] Question concernant le innerHtml

Sujet résolu
    31 décembre 2008 à 14:43:51

    Alors voila je vous expose le probleme: à l'interieur d'une de mes balises div , il y a plusieurs photos representant des missiles. Mon but est que, lorsqu'un missile touche un obstacle, celui-ci soit retiré de la balise div. J'ai tenté en vain une commande de ce type la, mais le comportement n'est pas celui attendu:
    document.getElementById('missile').innerHTML-='<img src="missile.gif" id="missile'+i+'"'
    


    Merci de votre aide.
    • Partager sur Facebook
    • Partager sur Twitter
      31 décembre 2008 à 15:27:48

      ah... c'est le -= qui m'a mis la puce à l'oreille.

      C'est clair que ça ne peut pas marcher... il faudrait que js soit capable de reconaitre la chaine de caractère représentée par ton image, puis de la soustraire aux reste de la chaine totale (qui comporte plusieurs images).

      Le -= ne peut fonctionner que sur des type number (je n'en vois pas d'autres).

      La solution que je donnerai est simple:

      Tu crées un tableau global qu'on nomme a_missiles.

      va a_missiles = new Array;

      Ensuite, tu stock toutes les images de missiles qui doivent se trouver dans le div.

      a_missiles[0] = '<img src="missile1">' ;
      a_missiles[1] = '<img src="missile2">' ;
      etc...

      tu peu conserver un identifiant pour chaque entrée avec une boucle (je ne connais pas ton code, mais tu trouveras facilement)

      for(var i=0; i<nb_missiles;i+1)
      a_missiles[i] = 'blabla' ;

      Et ensuite, lors de l'évènement "missile touche", eh bien tu soustrait le missile voulu à ton array.

      A chaque fois qu'il y a une mise à jour du tableau, tu en crées une chaine que tu place dans le innerHTML...

      Voilà... en espérant que ça peut aider!
      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        31 décembre 2008 à 16:13:28

        bonne soluce de fredu, mauvaise syntaxe.

        Mais va pas faire de la merde pour crée ta chaine à partir du tableau. Si tu reprends l'exemple d'au dessus, plus simplement:
        // c'est possible de faire encore plus simple mais passons.
        var missiles = [
            '<img src="missile.gif" id="missile0">',
            '<img src="missile.gif" id="missile1">'
        ];
        
        TonElement.innerHTML = missiles.join("");
        
        • Partager sur Facebook
        • Partager sur Twitter
          31 décembre 2008 à 19:28:07

          Tout d'abord merci à vous 2 pour vos réponses c'est sympa. Le probleme c'est que je suis déja passé par la creation d'un tableau de missile mais dans lequel j'ai stocké des ''objets'' de type missile. En fait désoler je vous ai peut etre mal explicité le probleme, le truc c'est que j'ai plusieurs rangées d'ennemis superposées mais lorsqu'un missile entre en contact avec un ennemi c'est la colonne complete qui est détruite au lieu du premier ennemi rencontré. Je vous donne le code complet de la creation des missiles ce sera peut etre plus clair pour vous, merci encore:


          function missile()
          			{
          			
          			this.creer=nouvo_missile
          			this.deplace=bouge_missile
          			var ys=((hauteur/2)+(hauteurespace-hauteurvaisseau))
          			var xs=vaisseau	
          			this.y=ys
          			this.testc=test_collision
          			
          			}
          
          
          
          		function nouvo_missile()
          		{
          			return '<img src="missile.gif" id="missile'+n+'" style="position:absolute;left:'+(vaisseau+60)+'px;top:'+((hauteur/2)+(hauteurespace-hauteurvaisseau))+'px;"/>'	
          		}
          		
          		
          		
          		function Tir()
          		{	
          		
          				if (n!=4)
          
          				{
          				miss[n]=new missile();
          				document.getElementById('missile').innerHTML+=miss[n].creer()	
          				n++
          				
          				}
          									
          		}
          		
          //les deux fonctions qui suivent permettent de faire monter le missile, la fonction controlleurmonte() est appelé par un timer au chargement du jeu.		
          		
          		function controlleurmonte() 
          		{
          				
          				for(i=0;i<miss.length;i++)
          				{
          				 
          				  miss[i].deplace();
          				  
          				  
          				}
          				
          		}
          		
          		
          		
          		function bouge_missile()
          		{
          				
          				
          			if( (this.y>parseInt(document.getElementById('espace').style.top)))
          			{
          				
          				this.y-=14
          				document.getElementById('missile'+i).style.top=this.y +'px'
          				this.testc()
          				
          			}
          			else
          			{
          			    
          			document.getElementById('missile'+i).src='';
          			
          				
          					if(i==3)
          					{
          					i=0
          					n=0
          					miss.length=null
          					document.getElementById('missile').innerHTML=''
          					
          					}
          			}
          			
          		}
          


          Voila pour ce qui est des missiles, pour la creation des ennemis j'ai suivi a peu pres le meme processus, je vous laisse uniquement la fonction qui permet de tester la collision entre le missile et l'ennemi. C'est dans cette fonction ou je rencontre le probleme avec le missile qui détruit tout sur son passage.

          function test_collision()
          			{
          			
          			var o;
          						
          			for (o=0;o<20;o++)
          			{
          			
          			
          			
          		
          			var ax=parseInt(document.getElementById('alien'+o).style.left);
          			var ay=parseInt(document.getElementById('alien'+o).style.top);
          			var rety=parseInt(document.getElementById('alien'+o).height);
          			var retx=parseInt(document.getElementById('alien'+o).width);
          			var my=parseInt(document.getElementById('missile'+i).style.top);
          			var mx=parseInt(document.getElementById('missile'+i).style.left);
          			
          		
          			
          		
          				
          					if ( ((ay>my)&&(my>(ay-rety)))&&(mx>ax&&mx<(ax+retx)) )
          					{
          					
          							
          					document.getElementById('missile'+i).src='';
          					
          					//c'est a ce point précis qu'il faudrait ''eliminer'' le missile qui a percuter le premier ennemi.
          						
          					document.getElementById('alien'+o).src='';	
          				
          					
          					}
          											
          					}
          				
          			}
          


          Encore merci à vous les gars, et bonne année à tous les zéros.
          • Partager sur Facebook
          • Partager sur Twitter
            1 janvier 2009 à 9:51:58

            var pkrsiofosefsef=document.getElementById('missile').innerHTML;
            pkrsiofosefsef=pkrsiofosefsef.replace('<img src="missile.gif" id="missile'+i+'"','');
            document.getElementById('missile').innerHTML=pkrsiofosefsef;
            


            je sais on peut faire plus court sans passer par la variable... mais comme il connais peut-être pas, c'est plus clair comme ça!
            • Partager sur Facebook
            • Partager sur Twitter
              1 janvier 2009 à 11:41:58

              Euh, pour enlever un élément le DOM n'est-il pas plus simple (surtout que, avec ta méthode xavierm02, cela revient à enlever tous les missiles puis les remettre :D , d'où perte de toute référence aux éléments des missiles et performances, hem, faibles quand il y en a beaucoup[1] !) ?
              var missile = document.getElementById('missile' +  i);
              missile.parentNode.removeChild(missile);
              

              [1] : De toute façon, tout usage du innerHTML produit cet effet, puisque quand on fait element.innerHTML += 'chaine'; , cela revient à element.innerHTML = element.innerHTML + 'chaine'; , donc à un remplacement du innerHTML de l'élément par une nouvelle valeur, ce qui signifie effacement puis réécriture :-°
              Un petit test ? Exécutez ce code :
              var a = document.getElementsByTagName('div')[0];
              alert(a.parentNode.nodeName);
              document.body.innerHTML += '';
              alert(a.parentNode.nodeName);
              

              Aucun effet en apparence sur la page (bien que ça puisse être long :D ), par contre, si le premier alert() affiche bien, comme on pouvait s'y attendre body (sur une page où le premier div est enfant direct du body, bien sûr :D ), en revanche le second fait une jolie erreur "TypeError: a.parentNode is null".
              Eh oui, quand on a changé le document.body.innerHTML , on a supprimé tous les enfants du body de son parent (et détruit totalement si il n'y avait pas de variable les contenant), donc le div n'est plus dans la page !
              Ca peut poser des problèmes, quand même :D (bon, y'en a un autre à la place, mais si on avait enregistré un div pour pouvoir le réutiliser plus tard, ben on peut plus !)
              Allez, un exemple plus convaincant (j'espère) sur les performances.
              Testez ces deux codes (sur une grosse page c'est mieux), censés produire le même effet, ajouter '' à la fin du html, (exécutés 50 fois pour qu'on voie bien la différence :D ) :
              for(var i = 0; i < 50; i++)
                  document.body.innerHTML += '';
              
              for(var i = 0; i < 50; i++)
                  document.body.appendChild(document.createTextNode(''));
              

              Comme c'est bizarre, le premier code est super lent, le second hyper rapide :-°
              Pour tout avouer, je ne me sers personnellement du innerHTML que pour vider un élément, j'ai la flemme de lui supprimer tous ses enfants via le DOM :D
              P.S. : Euh, j'ai peut-être un peu abusé des smilies, désolé.
              P.P.S. : Excusez-moi aussi pour ce long post pas trop en rapport avec le sujet original, j'ai pas fait gaffe à la taille en écrivant & j'ai pas trop envie de perdre le temps que j'ai passé à l'écrire :D
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                1 janvier 2009 à 12:51:49

                Sauf qu'en vrai tu travailles jamais sur le body directement (t'as déjà vu un designer qui met des <p> directement en fils du body? bah non il faut justifier les honoraires, alors on fout des tonnes de <div>). Donc ça sert a rien tout ce que t'as fait.

                Maintenant fait les même tests avec un div enfant, qui contient du html et tout le bordel. histoire d'avoir un truc utile. ensuite tu fait pas un append d'un noeud de texte mais d'un conteneur genre un div ou un span.

                Si on utilise innerHTML pour la rapidité c'est pas pour des prunnes. Essaie de crée et ajouter 50 ou 100 <div>. d'un coté avec innerHTML comme un bourrin de l'autre avec createElement("div");
                Tu vas moins rigoler
                • Partager sur Facebook
                • Partager sur Twitter
                  1 janvier 2009 à 20:41:33

                  (Mon code était juste un exemple, il avait pas pour but d'être utile :D )
                  Après un peu plus de tests, je maintient ce que je dis, avec tout de meme une petite nuance : innerHTML est plus rapide pour :
                  • Vider le contenu d'un élément
                  • Remplacer le contenu d'un élément par autre chose de totalement différence

                  En revanche, le DOM reste plus rapide (10 fois plus environ pour l'ajout consécutif de 50 fois <div class="classe"><p><img src="image.jpg" alt="toto" /><span>Salut</span></p></div> avec +=) pour :
                  • Ajouter un élément fils (ce que innerHTML ne sait pas "réellement" faire)
                  • Enlever un élément existant
                  • Modifier un élément existant
                  • Accéder précisément à un élément

                  Soit, en gros, innerHTML est bon pour effacement/réécriture (ou création), tandis que le DOM est meilleur pour modifier ce qui existe déja.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    1 janvier 2009 à 20:54:18

                    Faut voir la gueule de ton code, ça veux rien dire les chiffres que tu donnes.

                    tu me dit que ça (qui pourrait encore être optimisé),
                    for (var i=0;i<50;i++) {
                        document.body.appendChild(document.createElement("div"));
                    }
                    
                    /* optimisé */
                    
                    var el = document.body;
                    for (var i=0;i<50;i++) {
                        el.appendChild(document.createElement("div"));
                    }
                    


                    est 10 fois plus rapide que
                    var html = "";
                    for (var i=0;i<50;i++) {
                        html += "<div></div>";
                    }
                    document.body.innerHTML += html;
                    
                    /* encore plus rapide : */
                    
                    var html = [];
                    for (var i=0;i<50;i++) {
                        html.push("<div></div>");
                    }
                    document.body.innerHTML += html.join("");
                    



                    C'est comme ça qu'il faut utiliser innerHTML. Ça c'est moins rapide que le DOM? genre.


                    (edit) bien évidement que tu fais pas la même chose avec le dom et innerHTML. C'est pas fait pour faire la même chose. C'est comme tout, il faut savoir l'utiliser. Manifestement tu savais pas.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      1 janvier 2009 à 21:26:18

                      Oui, le code avec le DOM que tu donnes est plus rapide si le document est gros.
                      Sur la page d'accueil du SdZ, ton code avec innerHTML met 240ms, celui avec le DOM, 5ms (chez moi).
                      Et sur une page vide, si à la première exécution on a 3ms avec le DOM et 2ms avec innerHTML, à la seconde le innerHTML passe à 4ms, puis 6ms, puis 8ms, etc... alors que, avec le DOM, on reste à 3ms à chaque fois.
                      Enfin, arrêtons là cette discussion qui n'a plus grand chose à voir avec le sujet et codons chacun comme nous préférons :)
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        1 janvier 2009 à 21:49:31

                        Crois ce que tu veux. Si c'était le cas, jQuery n'utiliserait pas un système au dessus du DOM pour ses manipulations sur les élements html.

                        Le DOM à toujours été lent. C'est en train de changer en ce moment avec les nouveaux compilateur JS de google, mozilla (opéra a toujours été un peu – beaucoup parfois – plus rapide, mais ça aussi ça change).

                        Comme tu dis, bref. dsl pour le détournage de topic.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          2 janvier 2009 à 8:31:13

                          lol je vois que j'ai involontairement semé la panique. En tout cas merci cbasile06 pour ta participation. Et grand merci à toi aussi nod_ je me suis inspiré de la premiere réponse que tu m'avais donné et j'ai finalement reglé le probleme. Merci encore à vous 2.
                          • Partager sur Facebook
                          • Partager sur Twitter

                          [JS] Question concernant le innerHtml

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown