11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Je cherche désespérément la solution à ce problème qui me pourrit la vie de puis un certain temps.

J'explique.

1. J'ai une page principale (appelons-là pageprincipale.php) qui contient un div, et un lien (de type a onClick).

2. Lorsque l'utilisateur clique sur ce lien, une fonction Ajax est appelée pour remplir un div de la page, en asynchrone. Jusque là, tout va bien, ça fonctionne, la fonction Ajax est appelée, le div est rempli par le contenu d'une autre page php, appelons-là : partieajax.php

2. Dans cette partie Ajax, j'ai un bouton, censé appeler une fonction jQuery (slideToggle), pour déplier / replier un autre div (également dans cette partieajax.php), avec effet progressif.

Et c'est là le problème. Le bouton est inopérant, et la fonction jQuery n'est jamais appelée.

Je m'arrache les cheveux depuis deux jours sur ce soucis, donc, je vous poste une version hyper simplifiée du code, avec seulement les éléments dont je vous parle ci-dessus.

Merci par avance pour votre aide,

Stéphane

PS : je précise que si je transforme la partieajax.php, en page complète avec un head, un body, et les fonctions Ajax + inclusion de la librairie jQuery, le Toggle fonctionne parfaitement. C'est uniquement quand cette page est appelée via Ajax, que le lien jQuery devient inopérant à l'intérieur...

La page principale, "pageprincipale.php" :


<html>

<head>

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

<script type="text/javascript">

	function getXMLHttpRequest(){
		var XHR = false;
	        if (window.XMLHttpRequest) { 
	            XHR = new XMLHttpRequest();
	            if (XHR.overrideMimeType) {
	                XHR.overrideMimeType('text/xml');
	            }
	        } else if (window.ActiveXObject) { 
	            try {
	                XHR = new ActiveXObject("Msxml2.XMLHTTP");
	            } catch (e) {
	                try {
	                    XHR = new ActiveXObject("Microsoft.XMLHTTP");
	                } catch (e) {}
	            }
	        }

	        if (!XHR) {
	            alert('Abandon : Impossible de créer une instance XMLHTTP');
	            return false;
	        }
		return XHR;  
	}

	function RunAjax(url,id_resultat) { 

		var XHR = getXMLHttpRequest(); 
		XHR.onreadystatechange = function (){traitement_reponse(XHR,id_resultat);} 
		XHR.open('POST', url, true);
		XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');	
		XHR.send(null);	
		
	}

	function traitement_reponse(XHR,id_resultat){
		if(XHR.readyState == 4 ){
			if(XHR.status == 200) {		
					var reponse=XHR.responseText;
					document.getElementById(id_resultat).innerHTML=reponse;	
					$.unblockUI();			
				}
			}
	}

</script> 

</head>

<body>

<a onClick="RunAjax('partieajax.php', 'dynamiczone');">afficher la partie ajax</a>

<div id="dynamiczone">
</div>

</body>

</html>




La partie ajax "partieajax.php" :


<button class="lebouton">Replier / Deplier</button>
<p class="laclasse">
  voici le paragraphe a replier / deplier
</p>
 
<script>
$( ".lebouton" ).click(function() {
  $( ".laclasse" ).slideToggle( "slow" );
});
</script>


Modifié par WebDevParis (17 May 2017 - 17:29)
Salut Smiley smile

Tu as le problème récurrent de la portabilité du javascript Smiley smile

Un autre sujet à propos de datatable avait le même défaut Smiley smile

Le javascript s'exécute à la fin du chargement de la page "principale"
Tu renvois du JS en contenu HTML, normal, SAUF que le script ne se lance pas.. la page "principale" a déjà terminé elle Smiley cligne

Donc il faut que ton ajax lance ta fonction Smiley smile


<button class="lebouton">Replier / Deplier</button>
<p class="laclasse">
  voici le paragraphe a replier / deplier
</p>
 
<script>
function startAction(){
 $( ".lebouton" ).click(function() {
   $( ".laclasse" ).slideToggle( "slow" );
 });
}

startAction();
</script>


on crée une fonction, et on lance cette fonction dans la page Smiley smile quand l'html sera chargé, le js va créé la fonction puis avec son appel juste en dessous il va la lancer Smiley smile à partir de là, le listener jQuery se mettra en route Smiley smile

une autre variante est d'appeler la fonction après le rendu innerHtml...

et bien sur j'ai appelé la fonction startAction mais tu mets le nom que tu veux Smiley cligne
Arf, rien à faire, ça ne marche toujours pas Smiley decu

J'ai essayé de rajouter un alert("coucou"); au début de la fonction, mais il ne l'affiche pas, donc, il n'appelle même pas la fonction.

Pourtant, ton explication était logique ! je ne m'y connais pas du tout en JS, si ça se trouve, j'oublie un truc évident pour tout le monde Smiley langue
Modifié par WebDevParis (19 May 2017 - 22:14)
Bonjour,

Si tu peux, je pense qu'il faudrait tout simplement mettre ton JS directement dans la page principale :
$('#dynamiczone').on('click', '.lebouton', function(){
  $( ".laclasse" ).slideToggle( "slow" )
})



EDIT : Question des plus pertinentes : pourquoi charger jQuery et se faire ch*** comme un rat mort en utilisant Ajax de cette façon ???
Alors que tu pourrais remplacer "tout ton code actuel" par :
$.post( url, function(data) {
  $('#'+id_resultat).html(data);
  $.unblockUI();
})

Modifié par SolidSnake (22 May 2017 - 12:16)
Je reviens sur le sujet Smiley smile

j'ai dit plus haut : " une autre variante est d'appeler la fonction après le rendu innerHtml..."

ce qui donnerait ceci Smiley smile

Dans ta page d'appel

function traitement_reponse(XHR,id_resultat){
		if(XHR.readyState == 4 ){
			if(XHR.status == 200) {		
					var reponse=XHR.responseText;
					document.getElementById(id_resultat).innerHTML=reponse;	
					$.unblockUI();	
                                  startAction();		
				}
			}
	}


et dans ta page de retour d'ajax :

<button class="lebouton">Replier / Deplier</button>
<p class="laclasse">
  voici le paragraphe a replier / deplier
</p>
 
<script>
function startAction(){
 $( ".lebouton" ).click(function() {
   $( ".laclasse" ).slideToggle( "slow" );
 });
}
</script>


j'ai déplacé l'appel de fonction APRES le traitement du retour ajax Smiley cligne