webForumDet fria alternativet

Gå igenom DOM trädet omvänt fast i turordning

JavaScript

6 svar · 633 visningar · startad av Dino

Medlem sedan sep. 20011 914 inlägg
Frågan#1

Skulle vilja loopa igenom alla element på en sida och ändra dess style. Vill dock att stylen skall sättas på elementen i den här turordningen i DOM trädet nedan:

h2 > div > p > a > li > li > li > ul > span > span > p > h1 > div > h3 > div > body

eller denna

h1 > span > span > span > li > li > li > ul > a > p > p > h2 > div > div > h3 > div > body

<body>
<div>
	<h1></h1>
	<p>
		<span></span>
		<span></span>
		<ul>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<a href=""></a>
	</p>
	<p></p>
	<div>
		<h2></h2>
	</div>
</div>
<div>
	<h3></h3>
</div>
</body>

Går detta att uppnå?

Medlem sedan aug. 20039 340 inlägg
#2

Dags för lite fulkodning på morgonkvisten. Det övergripande målet verkar vara att gå igenom elementen dels inifrån och ut, och dels baklänges. Visserligen var väl inte det första förslaget tänkt att tas ordagrant, men jag gjorde det på kul ändå.
Koden jag kom fram till ser ut som följer, och gör precis det du ber om (Förutom att din kod innehåller en p mer än ordningen du först räknade ut samt att skriptet jag skrev även tycker att script-taggen ingår i uppräkningen)

<style>
*{
	border: 1px solid black;
	margin: 5px;
}
/* Colour the elements hierarchically for clarity */
*{			background: #fff;}
*>*{		background: #ddd;}
*>*>*{		background: #bbb;}
*>*>*>*{	background: #999;}
*>*>*>*>*{	background: #777;}

</style>
<body>
Cheat sheet: h2 > div > p > a > li > li > li > ul > span > span > p > h1 > div > h3 > div > body
<div>
	<h1></h1>
	<p>
		<span></span>
		<span></span>
		<ul>
			<li></li>
			<li></li>
			<li></li>
		</ul>
		<a href=""></a>
	</p>
	<p></p>
	<div>
		<h2></h2>
	</div>
</div>
<div>
	<h3></h3>
</div>
</body>
<script type="text/javascript">
function applyStyle(el){
	// Log the order of execution in an array
	taglog.push(el.tagName);
	// Print the element's tagName and where it is in the order to the element
	el.appendChild(document.createTextNode(el.tagName + "---" + order++));
}

// Walk backwards
function walk_b(el){
	var i = el.childNodes.length;

	// Walk recursively
	while(i--)
		if (el.childNodes[i].nodeType == 1) // Element node?
			walk_b(el.childNodes[i]);

	// Apply style
	applyStyle(el);
}

// Walk forward
function walk_f(el){
	var i = 0;

	// Walk recursively
	while(++i < el.childNodes.length)
		if (el.childNodes[i].nodeType == 1) // Element node?
			walk_b(el.childNodes[i]);

	// Apply style
	applyStyle(el);
}

window.onload=function(){
	// window. -> Declare in global scope
	window.order = 0;
	window.taglog=[];

	// walk...
	walk_f(document.body);

	// Display the log
	alert(taglog.join(" > "));
}

// </script>

Stilmallen överst färgar elementen som så att inre element blir mörkare och yttre ljusare. (Rent kosmetiskt för att lättare ¨ålla reda på dem)
I JS-koden går walk-funktionerna igenom varje element och först går igenom elementets barn och sedan applicerar applyStyle på sig självt, för att skapa ordningen inifrån och ut.
applyStyle kan uppenbarligen gör vad man vill, men i detta fall håller den koll på vad som görs med vilka element. (För debuggning)

Notera att walk_f kallar på walk_b medan walk_b kallar på sig självt. Att walk_f alls existerar beror på att du ville att diven med h3 i sig skulle hanteras sist. Är ordningen (Fram/baklänges) inte viktig kan du nöja dig med antingen walk_f eller walk_b. Men om du väljer walk_f se till att ändra anropet i funktionen till att kalla på sig själv.

Sedan får du gärna tala om vad du faktiskt vill uppnå... Kanske finns det ett enklare sätt.

Medlem sedan sep. 20011 914 inlägg
#3

Koden fungerar hur bra som helst, men nu kommer då del två av problematiken.

Det jag vill ändra för varje element är dess fontSize, vilket verkar vara svårare än jag trodde, då el.style.fontSize = s + "px"; inte fungerar.
Anledningen till att jag vill gå innefrån och utåt bland elementen är att jag försöker hindra att fontSizen ärvs från Parent till Child vilket jag märkt ger konstiga resultat. Någon kan kanske redan här rätta mig om hela tankesättet är fel.
Har kollat på en hel del fontResizer script, men inget verkar kunna gå igenom alla element och plusa på/dra ifrån x antal px.

Om det nu kan fungera i teorin så antar jag att en jquery lösning skulle vara det bästa. Vad anser ni?

Medlem sedan aug. 20039 340 inlägg
#4

Vad står s för? Alltså, i dasgläget, hur beräknar du s? Om du sätter storleken absolut i pixlar så bör inte ordningen spela någon roll. (Med mindre än att du hämtar fontSize från parent och använder det på något sätt.)
Och varför vill du ändra storleken? För att markera vissa element i en meny? För att låta användaren välja font-storlek? Något annat?
Du kanske borde kolla på enheten em, som sätter storleken relativt parent-elementet. En värde av 2em ger till exempel dubbla storleken mot parent.
Kan du visa lite "riktig" kod kanske?

Medlem sedan sep. 20011 914 inlägg
#5

Anledning: För att låta användaren välja font-storlek.
Enheten em: Föredrar px så det är det jag jobbar med.
"riktig" kod: Här är en variant som inte ger önskat resultat.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Untitled</title>
<style type="text/css">	
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,
address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,
var,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td 
{
	margin:0;padding:0;border:0;outline:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:top;
}
		 
body{font:11px/1.4 Verdana, Arial, Helvetica, Sans-Serif;}
h1{font-size:36px;} 		 
h2{font-size:18px;}     
#p1{font-size:14px;color:green;}  
#span2{font-size:8px;color:blue;}  
*{border: 1px solid black;margin: 5px;}     
*{background: #fff;}     
*>*{background: #ddd;}    
*>*>*{background: #bbb;}     
*>*>*>*{background: #999;}     
*>*>*>*>*{background: #777;}
</style>
</head>
<body>
<p>Cheat sheet: h2 &gt; div &gt; p &gt; a &gt; li &gt; li &gt; li &gt; ul &gt; span &gt; span &gt; p &gt; h1 &gt; div &gt; h3 &gt; div &gt; body</p>
<div>	
				<h1></h1>
				<p id="p1">			
							<span id="span1"></span>		
							<span id="span2"></span>				
							<a href=""></a>	
				</p>	
				<ul>			
							<li></li>			
							<li></li>
							<li></li>		
				</ul>	
				<p></p>	
				<div>		
							<h2></h2>
				</div>
</div>
<div>	
				<h3></h3>
</div>
<a href="javascript:decreaseFontSize();">-</a> <a href="javascript:increaseFontSize();">+</a>

<script type="text/javascript">
function applyStyle(el){
	// Log the order of execution in an array
	taglog.push(el.tagName);
	// Print the element's tagName and where it is in the order to the element
	el.appendChild(document.createTextNode(el.tagName + "---" + order++));
}

// Walk backwards
function walk_b(el){
	var i = el.childNodes.length;

	// Walk recursively
	while(i--)
		if (el.childNodes[i].nodeType == 1) // Element node?
			walk_b(el.childNodes[i]);

	// Apply style
	applyStyle(el);
}

// Walk forward
function walk_f(el){
	var i = 0;

	// Walk recursively
	while(++i < el.childNodes.length)
		if (el.childNodes[i].nodeType == 1) // Element node?
			walk_b(el.childNodes[i]);

	// Apply style
	applyStyle(el);
}

window.onload=function(){
	// window. -> Declare in global scope
	window.order = 0;
	window.taglog=[];

	// walk...
	walk_f(document.body);
}

var min=8;
var max=42;
function increaseFontSize() {   
			    var p = document.all;  
			   for(i=0;i<p.length;i++) {
      if(p[i].style.fontSize) {
         var s = parseInt(p[i].style.fontSize.replace("px",""));
			    if(s!=max) {
         s += 1;
      }
			 alert(s);
      p[i].style.fontSize = s+"px"
      } else {
         
      }
      
   }

 }
 function decreaseFontSize() {   
 				var p = document.all;   
 				for(i=0;i<p.length;i++) {
      if(p[i].style.fontSize) {
         var s = parseInt(p[i].style.fontSize.replace("px",""));
      } else {
         var s = 12;
      }
      if(s!=min) {
         s -= 1;
      }
      p[i].style.fontSize = s+"px"
   }   
 }
</script>
</body>
</html>
Medlem sedan aug. 20039 340 inlägg
#6

For the record tycker jag att din idé för att ändra storleken är... well, dåligt genomtänkt. Mitt råd är: gör om, gör rätt.
Här är ett enkelt exempel hur du kan använda em. Notera hur jag bara ändrar textstorleken för body och att resten av elementen följer med i storlek.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Untitled</title>
<style type="text/css">
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,
address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,
var,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td
{
	margin:0;padding:0;border:0;outline:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:top;
}

body{font:11px Verdana, Arial, Helvetica, Sans-Serif;}
h1{font-size:3.6em;}
h2{font-size:1.8em;}
#p1{font-size:1.4em;color:green;}
#span2{font-size:0.8em;color:blue;}
*{border: 1px solid black;margin: 5px;}
*{background: #fff;}
*>*{background: #ddd;}
*>*>*{background: #bbb;}
*>*>*>*{background: #999;}
*>*>*>*>*{background: #777;}
</style>
</head>
<body>
<p>Cheat sheet: h2 &gt; div &gt; p &gt; a &gt; li &gt; li &gt; li &gt; ul &gt; span &gt; span &gt; p &gt; h1 &gt; div &gt; h3 &gt; div &gt; body</p>
<div>
				<h1></h1>
				<p id="p1">
							<span id="span1"></span>
							<span id="span2"></span>
							<a href=""></a>
				</p>
				<ul>
							<li></li>
							<li></li>
							<li></li>
				</ul>
				<p></p>
				<div>
							<h2></h2>
				</div>
</div>
<div>
				<h3></h3>
</div>
<a href="javascript:changeFontSize(-1);">-</a> <a href="javascript:changeFontSize(1);">+</a>

<script type="text/javascript">
function applyStyle(el){
	// Log the order of execution in an array
	taglog.push(el.tagName);
	// Print the element's tagName and where it is in the order to the element
	el.appendChild(document.createTextNode(el.tagName + "---" + order++));
}

// Walk backwards
function walk_b(el){
	var i = el.childNodes.length;

	// Walk recursively
	while(i--)
		if (el.childNodes[i].nodeType == 1) // Element node?
			walk_b(el.childNodes[i]);

	// Apply style
	applyStyle(el);
}

// Walk forward
function walk_f(el){
	var i = 0;

	// Walk recursively
	while(++i < el.childNodes.length)
		if (el.childNodes[i].nodeType == 1) // Element node?
			walk_b(el.childNodes[i]);

	// Apply style
	applyStyle(el);
}

window.onload=function(){
	// window. -> Declare in global scope
	window.order = 0;
	window.taglog=[];

	// walk...
	walk_f(document.body);
}
</script>
<script type="text/javascript">

window.baseTextSize = 11;

function changeFontSize(d){
	window.baseTextSize = Math.min(42,Math.max(8,window.baseTextSize + d));

	document.body.style.fontSize = window.baseTextSize + "px";
}

</script>
</body>
</html>

Du kan även välja mellan flera olika stilmallar. Kolla t ex:
http://www.dynamicdrive.com/dynamicindex9/stylesheetswitcher.htm

Medlem sedan sep. 20011 914 inlägg
#7

Som du säger så får jag nog ta mig en funderare.

Tackar så mycket för all hjälp.

270 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
135 ms — deklarationer (db)
0 ms — hämta statistik (cache)
132 ms — hämta tråd, inlägg och bilagor (db)
130 ms — ändringar (db)