Toon posts:

[js][dom] object naar xhtml code converteren

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hoi mensen,

Ik heb in een website een dom object, namelijk een 'ul' met daarin een stapel aan childnodes (li's met soms ook weer wat ul's en li's daarin en daarin weer links). Nu is het mijn bedoeling om de xhtml code van dit object te krijgen. Wat ik eigenlijk alleen wil is de <ul> <li> en <a> tags met hun eindtags. Ik heb geprobeerd dit met innerHTML te realiseren, maar dit levert wel erg vieze, onbetrouwbare resultaten op als je kijkt naar de output van verschillende browsers. Mozilla kan ik nog enigzins in de richting krijgen met de normalize() functie..

Ik ben nu dus met innerHTML bezig, is het het beste om dit dan maar 'op te ruimen'? Het lijkt me niet echt betrouwbaar.

Een ander idee is misschien om zelf het ding recursief door te lopen, maar dan zit ik met het probleem van de start/eindtags.

Kan iemand me op weg helpen? B.v.d.!

Verwijderd

Ik zou gaan voor een recursieve functie. Een switchje op de nodeName, en klaar is kees.

Bijvoorbeeld:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function getHTML(obj)
{
    var text;
    
    for (var i=0;i<obj.childNodes.length;i++)
    {
        switch (obj.childNodes[i].nodeName.toLowerCase())
        {
            case '#text':
                text+=obj.childNodes[i].nodeValue;
                break;
            case 'div':
                text+='<div>'+getHTML(obj.childNodes[i])+'</div>';
                break;
        }
    }
    
    return text;
}


Uiteraard moet je hier ook nog de nodige attributes e.d. afvangen, maar dit moet je tenminste op weg helpen.

[ Voor 55% gewijzigd door Verwijderd op 01-07-2005 00:33 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:31

crisp

Devver

Pixelated

bedoel je zoiets?
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<div id="content">
<ul><li>foo</li><li><a href="#">foo</a><ul><li>foo</li></ul></li><li><a href="#">foo</a><ul><li><a href="#">foo</a><ul><li>foo</li></ul></li></ul></li></ul>
</div>
<script type="text/javascript">

function showTree(el,level)
{
    if (!level) level = 0;
    var i = 0, j = el.childNodes.length, tree = '';
    while (i < j)
    {
        if (el.childNodes[i].nodeType == 1)
        {
            tree += strRepeat('\t', level) + '<' + el.childNodes[i].tagName.toLowerCase() + '>\n';
            tree += showTree(el.childNodes[i], level+1);
            tree += strRepeat('\t', level) + '</' + el.childNodes[i].tagName.toLowerCase() + '>\n';
        }
        else if (el.childNodes[i].nodeType == 3 && /[^\t\n\r ]/.test(el.childNodes[i].data))
        {
            tree += strRepeat('\t', level) + '{text}\n';
        }

        i++;
    }

    return tree;
}

function strRepeat(chr, num)
{
    var ret = '';
    while (num--) ret += chr;
    return ret;
}

var tree = showTree(document.getElementById('content'));
document.write('<pre>', tree.replace(/</g, '&lt;'), '<\/pre>');

</script>

Intentionally left blank


Verwijderd

Topicstarter
Crisp, wat doet jouw script precies? Het geeft hier nogal een aparte output namelijk!

Ik ben verder gegaan met de code van postzegel, ik snap alleen niet waarom ik deze output krijg:

Afbeeldingslocatie: http://www.joostbastings.com/ul.png

dit is de code die ik nu heb:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function getHTML(obj)
{
    var text;
    
    for (var i=0;i<obj.childNodes.length;i++)
    {
        switch (obj.childNodes[i].nodeName.toLowerCase())
        {
            default:
                alert('ooops');
            break;
            case '#text':
                text+=obj.childNodes[i].nodeValue;
                break;
            case 'a':
                text+='<a href=\"'+obj.childNodes[i].href+'\">'+
                    getHTML(obj.childNodes[i])+'<\/a>';
                break;
            case 'li':
                text+='<li>'+getHTML(obj.childNodes[i])+'<\/li>';
                break;
            case 'ul':
                text+='<ul>'+getHTML(obj.childNodes[i])+'<\/ul>';
                break;
            case 'span':
                text+='<span>'+getHTML(obj.childNodes[i])+'<\/span>';
                break;
        }
    }    
    return text;
}


Hoe kom ik aan die undefined?

[ Voor 27% gewijzigd door Verwijderd op 01-07-2005 10:38 ]


Verwijderd

Het kan natuurlijk veel simpeler. In principe kun je bijna elke tag op dezelfde tag behandelen:

code:
1
text+='<'+obj.childNodes[i].nodeName.toLowerCase()+getAttributes(obj.childNodes[i])+'>'+getHTML(obj.childNodes[i])+'</'+obj.childNodes[i].nodeName.toLowerCase()+'>';


Als je dat dus in de default: van je switch zet, en de paar uitzonderingen apart (#text enzo) ben je bijna klaar.

Vervolgens hoef je alleen nog maar een functie getAttributes te maken die van een object alle attributes doorgeeft die van belang zijn.

[ Voor 7% gewijzigd door Verwijderd op 01-07-2005 11:06 ]


Verwijderd

Topicstarter
Hmm ik heb hem nu zo gemaakt, maar nog steeds duiken er overal (en ook aan het begin??) "undefined" tekstjes op. Ik kom er gewoon niet uit waar dat de oorzaak van is? Het zijn geen textnodes i.i.g.

Verwijderd

Post anders even een link naar de complete code. Dan kunnen wij meekijken.

Verwijderd

Topicstarter
http://www.joostbastings.com/menueditor.html

Voor de html code, zoek op "getHTML" of "function getHTML(obj)"

Boven die functie staat de code waar getHTML wordt gebruikt.

groet,

Verwijderd

Ik zie het al. Er worden lege textNodes aangemaakt. Als je daarvan de nodeValue opvraagt, dan krijg je een undefined terug.

Verwijderd

Topicstarter
Bedankt voor het kijken! Het is mijn eerste javascript projectje dus het is nog niet echt optimaal (vooral de Init() functie..)

Maar goed, hoe denk je dat ik dit kan oplossen? Want waar worden die lege textnodes ingevoegd?

/edit
Als je een alert zet op de textnode switch, dan krijg je maar 1 alert in totaal. De andere "undefined" kunnen dus geen textNodes zijn?

[ Voor 25% gewijzigd door Verwijderd op 01-07-2005 12:02 ]


Verwijderd

Browsers doen dit nogal eens zelf. Het beste is om in je script te kijken of een textNode wel een waarde heeft, voordat je er iets mee doet.

Bijvoorbeeld:

code:
1
if (obj.childNodes[i].nodeValue;) text+=obj.childNodes[i].nodeValue;

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:31

crisp

Devver

Pixelated

Verwijderd schreef op vrijdag 01 juli 2005 @ 10:36:
Crisp, wat doet jouw script precies? Het geeft hier nogal een aparte output namelijk!
Mzzz, dat komt door mijn HTML rechten; de laatste regel moet luiden:
JavaScript:
1
document.write('<pre>', tree.replace(/</g, '&lt;'), '<\/pre>');

Intentionally left blank


Verwijderd

Topicstarter
Verwijderd schreef op vrijdag 01 juli 2005 @ 12:02:
Browsers doen dit nogal eens zelf. Het beste is om in je script te kijken of een textNode wel een waarde heeft, voordat je er iets mee doet.

Bijvoorbeeld:

code:
1
if (obj.childNodes[i].nodeValue;) text+=obj.childNodes[i].nodeValue;
DIt helpt niet, een lege textnode geeft nog steeds een waarde terug. Maar, er is maar 1 textnode die een undefined geeft, de rest.. geen id?

Verwijderd

Topicstarter
uit pure wanhoop heb ik de undefined-crisis maar "opgelost" met een regular expression, die simpelweg de tekst 'undefined' vervangt met niets.. mocht iemand nog willen kijken naar waar de undefined vandaan komen, graag! Ik kom daar namelijk gewoon niet meer uit, ik denk niet recursief genoeg waarschijnlijk ;)

Verwijderd

Als jij een voorbeeld online zet, zal ik er naar kijken en het voor je oplossen :) /me is liev vandaag...

Verwijderd

Topicstarter
http://www.joostbastings.com/menueditor.html

daar staat ie

kijk naar de functie 'sharkvisOpslaan' en daaronder voor getHTML

bedankt :)
Pagina: 1