11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous,
Voila je viens de me mettre à la gestion d'évènement avec javascript afin de réaliser un outil de statisitiques simple qui me permettra de savoir combien de fois un formulaire a été chargé et combien de fois il a été validé.
Jusque la tout va bien, j'ai créé un javascript qui ajout une gestion du onload et je veux ajouter la gestion du submit sachant qu'il doit fonctionner si la page contiend plusieurs formulaires.
Voila le script :

// JavaScript Document
var gk=window.innerWidth?1:0 //gecko ; 
var ie=navigator.appVersion.substr(17,4)=="MSIE"?1:0;
// Ajout d'une action sur un événement
var url_page=window.location.href;
function req(type,url_site)
{ 
   var stats_devictio='<img src="http://stats.devictio.com/formStat.php?type='+type+'&url='+url_site+'" border="0" width="5px" height="5px" style="display:none">';
   var code=document.getElementsByTagName("body");
   code[0].innerHTML+=stats_devictio;
} 
function addEvent(obj, evType, fn, useCapture)
{
  if (obj.addEventListener)
  {
    obj.addEventListener(evType, fn, useCapture);
    return false;
  }
  else
  	if (obj.attachEvent)
	{
    	var r = obj.attachEvent("on"+evType, fn);
    	return r;
  	}
	else
	{
    	alert("Impossible d'ajouter l'evenement");
  	}
}// Arrête la poursuite de l'évènement
var stopEvent = function(e)
{
	if(e.preventDefault)
	{
		e.preventDefault();
		e.stopPropagation();
	}	// code standard DOM
	else
		if(ie)
		{
			e.cancelBubble = true;
			e.returnValue = false;
		}	// code propriétaire MSIE
	return false; // pour les autres
}

function addStats(e)
{
	req('add',url_page);
}
function editStats(e)
{
	req('edit',url_page);
	alert('ok');
}
addEvent(window,"load",addStats,false);
addEvent(document."submit",editStats,false);


Est-ce que quelqu'un de plus expérimenté ou du moins mieux renseigné pourrait m'expliquer pourquoi sous firefox lorsque que je valide le formulaire, le message 'ok' s'affiche mais le formulaire n'est pas envoyé et est meme effacé ?

merci d'avance Smiley biggrin
Salut nicoss01,

alors déjà ta fonction req n'est pas très propre: tu crées une image pour chaque requête. De plus, tu ne dois pas utiliser de guillemets pour les valeurs dans le GET. Enfin, préfère une iframe à une image, même si les 2 solutions ne sont pas super... Quelque chose comme ceci serait plus approprié :
function req(type, url_site)
{
	var stats_devictio = document.getElementById('stats_devictio');
	if(!stats_devictio) {
		stats_devictio = document.createElement('iframe');
		stats_devictio.style.display = 'none';
		stats_devictio.id = 'stats_devictio';
		document.body.appendChild(stats_devictio);
	}
	stats_devictio.src = 'http://stats.devictio.com/formStat.php?type=' + type + '&url=' + url_site;
}
Il en est de même pour ta fonction addEvent:
function addEvent(obj, evType, fn, useCapture)
{
	if(obj) {
		if(obj.addEventListener)
			return obj.addEventListener(evType, fn, useCapture);
		if(obj.attachEvent)
			return obj.attachEvent("on" + evType, fn);
	}
	return false;
}
La fonction stopEvent peut-être écrite très simplement comme ceci :
function stopEvent(e)
{
	if(e.preventDefault)
	{
		e.preventDefault();
		e.stopPropagation();
	}
	e.cancelBubble = true;
	e.returnValue = false;
}
Ensuite, l'événement "submit" est géré par le formulaire ciblé et non document. Ce qui implique que l'ajout de cet événement doit se faire après chargement du formulaire:
addEvent(myFormElement, "submit", editStats, false);
Pour finir, tu oublies de stoper la propagation de l'événement "submit" dans ta fonction editStats. De ce fait, rien n'empêche la page d'être rechargée, ce qui te fait peut-être penser que le formulaire s'efface:
function editStats(e)
{
	req('edit', url_page);
	stopEvent(e);
	alert('ok');
}

Après tout ça, dis nous si les choses vont mieux (ou pas)
Bon courage.
Tout d'abord merci Ze Nenex pour ta réponse qui a bien fait avancé mon
problème,
le soucis qu'il me reste est le suivant :
Sous Firefox le chargement de la page est enregistré dans les stats ainsi que la validation mais le formulaire n'est pas posté ensuite.
Sous IE 7 le systeme ne fonctionne pas du tout les stats n'enregistrent rien
voici le code que j'utilise :

// JavaScript Document
var gk=window.innerWidth?1:0 //gecko ; 
var ie=navigator.appVersion.substr(17,4)=="MSIE"?1:0;
// Ajout d'une action sur un événement
var url_page=window.location.href;
function req(type, url_site)
{
	var stats_devictio = document.getElementById('stats_devictio');
	if(!stats_devictio) {
		stats_devictio = document.createElement('iframe');
		stats_devictio.style.display = 'none';
		stats_devictio.id = 'stats_devictio';
		document.body.appendChild(stats_devictio);
	}
	stats_devictio.src = 'http://stats.devictio.com/formStat.php?type=' + type + '&url=' + url_site;
}
function addEvent(obj, evType, fn, useCapture)
{
	if(obj) {
		if(obj.addEventListener)
			return obj.addEventListener(evType, fn, useCapture);
		if(obj.attachEvent)
			return obj.attachEvent("on" + evType, fn);
	}
	return false;
}
function stopEvent(e)
{
	if(e.preventDefault)
	{
		e.preventDefault();
		e.stopPropagation();
	}
	e.cancelBubble = true;
	e.returnValue = false;
}
function addStats(e)
{
	req('add',url_page);
	stopEvent(e);
}
function editStats(e)
{
	req('edit', url_page);
	stopEvent(e);
}
addEvent(window,"load",addStats,false);
var formu=document.getElementsByTagName('form');
for(i=0;i<formu.length;i++)
{
	addEvent(document.getElementsByTagName('form')[i],"submit",editStats,false);
}

je ne vois pas ce qui cloche la dedans, si quelqu'un a une idée sur le sujet, merci d'avance de votre aide Smiley lol [/i]
nicoss01 a écrit :
Sous Firefox le chargement de la page est enregistré dans les stats ainsi que la validation mais le formulaire n'est pas posté ensuite.
Ce qui est tout à fait logique: la fonction stopEvent empêche l'événement submit d'être validé, c'est le rôle de la méthode preventDefault (propriété returnValue pour IE). En enlevant la ligne correspondante dans ta fonction editStats, l'url indiquée dans l'attribut action de ton formulaire sera envoyée. Tout dépend du comportement que tu veux.
nicoss01 a écrit :
Sous IE 7 le systeme ne fonctionne pas du tout les stats n'enregistrent rien.
Je n'ai pas IE7 au boulot, désolé de t'avoir livré du code non fonctionnel. Pour faire les choses bien, tu devrais utiliser un objet XMLHttpRequest depuis ta fonction req (il me semble que cet objet est natif dans IE7, mais prévoir le comportement pour les versions antérieures)
le probleme s'est l'objet XMLHttpRequest ne peut pas appeler un fichier externe au site où est inséré cet objet (pour des questions de sécurité bien sur),donc je vois pas comment ça pourrait me servir.
Donc avec la suppression de stopEvent() dans la fonction editStats et le formulaire est validé sous firefox et les stats enregistrent tout.
Il me reste plus qu'a trouver pourquoi rien ne fonctionne sous IE 7.
Modérateur
Salut, Smiley smile

Pour la fonction stopEvent, il faut ajouter un return false à la fin car Safari a un bug à ce niveau. Il passe le test e.preventDefault mais n'interprète pas correctement les instructions du bloc. Quelquechose comme ceci serait mieux :
function stopEvent(e) {
	if(e && e.stopPropagation && e.preventDefault) {
		e.stopPropagation();
		e.preventDefault();
	}
	else if(e && window.event) {
		window.event.cancelBubble = true;
		window.event.returnValue = false;
	}
	return false;
}
Pour le problème sous IE7 : Lorsque tu passes par une iframe cachée, tu dois mettre à la fois un id et un name de même valeur pour une question de compatibilité. De même, certains navigateurs n'aiment pas les iframes générées via JS, ce pourquoi on trouve souvent les iframes cachées en direct dans le code html. Il se pourrait que ça joue.
Regarde l'exemple du chapitre 2 du zip Professional Ajax 1st Edition de cette page pour voir comment faire. Smiley cligne

Par ailleurs, comme te l'a dit Ze Nenex, il serait préférable de passer par un objet XHR plutôt qu'une iframe cachée afin de faire ta requête de manière asynchrone. Tu ne peux effectivement pas appeler un fichier externe de cette manière mais rien ne t'empêche de faire une requête sur un fichier php situé sur ton serveur, ce dernier prenant le relais pour aller chercher l'info sur le site externe.

PS : ça te sert le code suivant ? Smiley rolleyes
var gk=window.innerWidth?1:0 //gecko ; 
var ie=navigator.appVersion.substr(17,4)=="MSIE"?1:0;
Si tu dois isoler un navigateur, mieux vaut tester les propriétés/méthodes plutôt que de faire de la détection navigateur... Ca, c'est vraiment en dernier recours. Par exemple, pour isoler IE, tu n'as qu'à tester si le navigateur comprend les activeX ou encore window.attachEvent, etc...
Modérateur
nicoss01 a écrit :
Voila je viens de me mettre à la gestion d'évènement avec javascript afin de réaliser un outil de statisitiques simple qui me permettra de savoir combien de fois un formulaire a été chargé et combien de fois il a été validé.
Pourquoi passes-tu par JS au fait ? C'est tout à fait possible en PHP... Ce serait même mieux pour éviter de dépendre du client. Smiley smile La partie JS est optionnelle ici... pour ne pas dire inutile.
Merci koala64 pour tes infos très utiles.
Pour repondre à ta question, je ne peux pas utiliser le php car ce script est destiné à être installé rapidement sur tout type de serveur php ou asp,...
Pour l'ajax je sais que l'on peut mettre un fichier en local qui serve de "passerelle" pour utiliser l'objet XMLHttpRequest le problème est que ce script doit pouvoir etre installé sans avoir à uploader d'autres fichiers, car en centralisant le fichier js, cela me permet de le mettre à jour sans avoir à mettre à jour les fichiers contenus sur d'autres serveur.