innerHTML et le w3c

Vous ne le saviez peut-être pas mais innerHTML n'est pas reconnu par le W3C… Peut-importe, me direz-vous car tous les navigateur (ou presque ?) le gère.
Il n'empêche que l'on peu faire la même chose en utilisant le DOM
Certes, c'est moins pratique, mais c'est plus rigoureux.

J'ai développer une fonction qui va, lorsqu'on lui passe une chaîne de caractère contenant des balises, créer les balises et le contenu adapter…
L'utilisation ressemble donc a innerHTML.

javascript
DOMinnerHTML(document.body,'add',"<em>tic</em> et <strong>tac</strong>");

La fonction

javascript
function trim(string) {
	return string.replace(/(^\s*)|(\s*$)/g,'');
}
function DOMinnerHTML(obj,method,data) {
	/*si vide, pas la peine de ocntinuer*/
	if (data.length==0) return '';
	/*detection du < de début de balise*/
	var pbalise=data.indexOf('<');
	if (pbalise>0) {
		var text=data.substring(0,pbalise);
		/*supprime ce qu'on va ajouter*/
		data=data.substring(pbalise,data.length);
		/*ajoute le node*/	
		text=document.createTextNode(text);
		if (method=="add")
			obj.appendChild(text);
		else
			obj.replaceChild(text, obj.firstChild);
		DOMinnerHTML(obj,'add',data);
	}
	else if (pbalise==0) {
		/*ici, on commence par une balise*/
		var posSelfClose=data.indexOf('/>');		
		var posClose=data.indexOf('>');
 
		/*detection des attributs*/
		var balise=trim(data.substring(1,((posSelfClose==posClose-1)?posSelfClose:posClose)));	
 
		var attr=Array();
		if (balise.indexOf('=')!=-1)
			attr=balise.split('=');
 
		if (balise.indexOf(' ')!=-1)
			balise=balise.substring(0,balise.indexOf(' '));
 
		if (posSelfClose==posClose-1) {
			/*cas d'une balise autofermé*/
			/*on crée la balise et on continu en mode normal*/
			var cible=document.createElement(balise);
			/*supprime la balise des data restante*/
			data=data.substring(posSelfClose+2,data.length);
		} else {
			/*creation de la blise puis recursivité pour le contenu*/
 
			var cible=document.createElement(balise);
			/*place a part la balise et son contenu*/
			var contenu=data.substring(posClose+1,data.length);
			contenu=contenu.substring(0,contenu.indexOf('</'+balise));
			/*supprime la balise et son contenu des data restante*/
			data=data.substring(data.indexOf('</'+balise)+3+balise.length,data.length);
			if (contenu!='')
				DOMinnerHTML(cible,'add',contenu);
 
		}
 
 
 
		for(var i = 0; i <= attr.length-1; i++) {	
			if (!attr[i]) continue;
			if (!attr[i+1]) continue;		
			if (trim(attr[i])=='') continue;
			if (trim(attr[i+1])=='') continue;	
 
			/*recupere l'attribut*/
			var att=trim(attr[i].substring(attr[i].indexOf(' '),attr[i].length));
			/*pour la valeur, on vire le 1er "*/
			attr[i+1]=attr[i+1].substring(1,attr[i+1].length);			
			/*puis on chppe la parti avant le " restant*/
			var attVal=trim(attr[i+1].substring(0,attr[i+1].indexOf('"')));
 
			var tmp=attr[i+1].substring(attVal.length+2,attr[i+1].length);
 
			if (document.all) {
				var tmp2=att.toLowerCase();
				if (tmp2=="class")
					cible.setAttribute("className", attVal);
				else if (tmp2.substring(0,2)=="on") /*evenement onclick, onmouseover, etc...*/
					eval('cible.'+att+' = function() {'+attVal+'};');
				else if (tmp2=="checked")
					cible.setAttribute("defaultChecked", attVal);
				else if (tmp2=="style") {
					/*on doit décomposé et appliquez les attribut 1 à 1*/
					var sty=attVal.split(';');
					for(var j = 0; j <= sty.length-1; j++) {	
						var style=sty[j].split(':');
						if (trim(style[0])=='') continue;
						/*traduction des mot composé en camelCase*/
						var pt=style[0].indexOf('-');
						if (pt!=-1) {
							var tmp3=style[0].substring(pt+1,pt+2);
							tmp3=style[0].substring(0,pt)+tmp3.toUpperCase()+style[0].substring(pt+2,style[0].length);
							style[0]=tmp3;
						}
						cible.style.setAttribute(style[0], style[1]);	
					}
				} else
					cible.setAttribute(att, attVal );				
			}  else
				cible.setAttribute(att, attVal );
 
			if (tmp!='')
				attr[i+1]="_ "+tmp;
		}
 
		if (method=="add")
			obj.appendChild(cible);
		else
			obj.replaceChild(cible, obj.firstChild);
 
		DOMinnerHTML(obj,'add',data);
	}
	else if (pbalise=-1) {
		/*ajoute le texte trouvé*/	
		var text=document.createTextNode(data);
		if (method=="add")
			obj.appendChild(text);
		else
			obj.replaceChild(text, obj.firstChild);
	}
}

Utilisation

DOMinnerHTML(obj,method,data)
Voici les paramètres a passer à la fonction :

  • obj : l'objet que l'on désire modifier
  • method : “add” ou “replace” selon que vous voulez ajouter du contenu ou remplacer le contenu
  • data : une chaîne de type string contenant les données (html ou simple texte) que vous voulez mettre dans l'objet.
le contenu de data DOIT être au format xhtml, a savoir les balises doivent toujours être fermées : &lt;br /&gt;, &lt;img /&gt;, etc…

Si vous tentez d'insérer un tableau, N'oubliez pas la balise &lt;tbody&gt; sans quoi votre tableau n'apparaitra pas sous IE

Reste a faire

Pour l'instant, tous ne fonctionne pas.

  • Pour l'instant la fonction est “write only” impossible de récupérer le contenu d'un objet
  • on ne peu utiliser ni égal ( = ) ni guillemet ( ” ) dans le contenu d'un attributs

N'hésitez pas a nous faire part des évolution que vous apporterez a cette fonction !


23/05/2006 11:30 -

iDo –