[javascript] HTML attributen herkennen middels een regexp

Pagina: 1
Acties:

  • kaydie
  • Registratie: Juni 2006
  • Laatst online: 06-01-2022
Graag hulp bij het volgende probleem:
Ik ben nu al een tijdje aan het klooien, om met behulp van een regExp in javascript een string in stukjes in een array te krijgen maar het wil maar niet lukken.
De string is een opsomming van attributen voor een element, die los van elkaar in een array gestopt moeten worden.
Hier een voorbeeld;
code:
1
2
3
4
string='id="test" class="abc def" src="http://dummy.host/images/foto.jpg" alt="zomaar een foto"';

reg=/(#regular expression)/;
atts=string.match(reg);
Wat ik graag zou zien was dat na de string door de regEx gehaald te bebben ik de volgende array over hield
code:
1
2
3
4
atts[0]='id="test"'
atts[1]='class="abc def"'
atts[2]='src="http://kaydies.com/images/kay_boom_thumb.jpg"'
atts[3]='alt="foto van kaydie"'

als regular expression daar voor had ik de volgende (niet werkende) regEx bedacht...
code:
1
/\w+="[\w\D]+(?!=")"/
Iemand een idee wat er fout gaat?

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 12-02 10:41

chem

Reist de wereld rond

Waarom gebruik je regexps, op naar ik vermoed een innerHTML, ipv getAttribute ?

Klaar voor een nieuwe uitdaging.


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:34

crisp

Devver

Pixelated

Je zou dan beter kunnen splitten op whitespace lijkt me, hoewel dit ook valid HTML is:
HTML:
1
<div id = "foo">

sowieso zit je met het feit dat ook single quotes of soms ook geen quotes om je attribuut-waarden toegestaan zijn, en je ook nog minimized attributen hebt zoals 'disabled' 'checked' etcetera.

Intentionally left blank


  • kaydie
  • Registratie: Juni 2006
  • Laatst online: 06-01-2022
@chem
Ik ben bezig met een scriptje waarbij ik makkelijk nieuwe elementen kan aanmaken met één function call, zoiets als:
code:
1
img = element.build("img",'id="test" class="abc def" src="http://dummy.host/images/foto.jpg" alt="zomaar een foto"');

@crisp
Je hebt gelijk, maar omdat ik het vooralsnog alleen ga gebruiken om zelf nieuwe elementen aan de DOM toe te voegen, heb ik daar nu nog niet zo'n last van.

Bedankt voor het meedenken :)

de regExp die wel werkt:
code:
1
/\w+="[^"]*"/g
(thx iJoost!)

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:34

crisp

Devver

Pixelated

Waarom geef je dan niet gelijk al een array mee aan je build method?

Intentionally left blank


  • Victor
  • Registratie: November 2003
  • Niet online
Gebruik dan zoiets:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function domObjectBuilder(domObject) {
    var _newElement = document.createElement(domObject.elementType);

    if (typeof domObject.contents == "string") {
        _newElement.appendChild(document.createTextNode(domObject.contents));
    } else if (typeof domObject.contents == "object") {
        _newElement.appendChild(domObject.contents);
    }

    if (domObject.attributes) {
        // Cross browser class attributes
        if (domObject.attributes["className"]) {
            domObject.attributes["class"] = domObject.attributes["className"];
        }

        for (var _attribute in domObject.attributes) {
            _newElement.setAttribute(_attribute, domObject.attributes[_attribute]);
        }
    }

    return _newElement;
}


En om een H1 element te genereren met als className "test" en als id "heading". Zet meteen automagisch de tekst "Test" erin:
JavaScript:
1
2
3
4
5
6
7
8
domObjectBuilder({
    elementType : "h1",
    contents    : "Test",
    attributes  : {
        className : "test",
        id        : "heading"
    }
}));


Alleen het crossbrowser setten van de className is nog niet helemaal netjes, maar dan had ik zo snel nog geen oplossing voor.

  • kaydie
  • Registratie: Juni 2006
  • Laatst online: 06-01-2022
@crisp
Eh... Ja, goeie vraag, waarom niet eigenlijk :)

@King_Louie
Nice, ik had zelf iets soortgelijks bedacht; (w.i.p.)...
JavaScript:
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
element = {
    create : function(e,n){
        if (n == "element") return document.createElement(e);
        else if (n == "text") return document.createTextNode(e);
    },
    add : function(e,f,p){
        if (p == "before") e.insertBefore(f,e.firstChild);
        else e.appendChild(f);
    },
    attr : function(e,n,v){
        var exists = null;
        for (var i = 0; i < e.attributes.length; i++) {
            if (e.attributes[i].name == n) exists = true;
        }
        if (exists) e.setAttribute(e.attributes[exists],v);
        else e.setAttribute(n,v);
    },
    build : function(e,a,t){
        elm = this.create(e,"element");
        if(a !== ""){
            var reg = /\w+="[^"]*"/g
            atts = a.match( reg )
            for (var i = 0; i < atts.length; i++) {
                att = atts[i].split("=");
                if (att.length > 1)
                    this.attr(elm,att[0],att[1].replace(/[\"]/g, ""));
                else
                    this.attr(elm,atts[i],atts[i]);
            }
        }
        if(t){
            txt = this.create(t,"text");
            this.add(elm,txt);
        }
        return elm;
    }
}

  • Victor
  • Registratie: November 2003
  • Niet online
kaydie schreef op maandag 28 augustus 2006 @ 19:48:
@crisp
Eh... Ja, goeie vraag, waarom niet eigenlijk :)

@King_Louie
Nice, ik had zelf iets soortgelijks bedacht; (w.i.p.)...
JavaScript:
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
element = {
    create : function(e,n){
        if (n == "element") return document.createElement(e);
        else if (n == "text") return document.createTextNode(e);
    },
    add : function(e,f,p){
        if (p == "before") e.insertBefore(f,e.firstChild);
        else e.appendChild(f);
    },
    attr : function(e,n,v){
        var exists = null;
        for (var i = 0; i < e.attributes.length; i++) {
            if (e.attributes[i].name == n) exists = true;
        }
        if (exists) e.setAttribute(e.attributes[exists],v);
        else e.setAttribute(n,v);
    },
    build : function(e,a,t){
        elm = this.create(e,"element");
        if(a !== ""){
            var reg = /\w+="[^"]*"/g
            atts = a.match( reg )
            for (var i = 0; i < atts.length; i++) {
                att = atts[i].split("=");
                if (att.length > 1)
                    this.attr(elm,att[0],att[1].replace(/[\"]/g, ""));
                else
                    this.attr(elm,atts[i],atts[i]);
            }
        }
        if(t){
            txt = this.create(t,"text");
            this.add(elm,txt);
        }
        return elm;
    }
}
Ik kan een lichte WTF?! toch niet onderdrukken.

Zelden zo'n complex stukje code voor zoiets simpels gezien. En je lijkt ook niet te weten dat je ook arrays, object en zelfs functies als argument aan een functie mee kan geven, want ik zie nog steeds allerlei lelijke regExp constructies om een array van attributen te bouwen.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:34

crisp

Devver

Pixelated

Dat begint inderdaad verdacht veel te lijken op
JavaScript:
1
document.createElement('<input type="text" name="foo">');

(en ja, dat werkt... in IE alleen uiteraard ;) )

Intentionally left blank


  • kaydie
  • Registratie: Juni 2006
  • Laatst online: 06-01-2022
@King_Louie
Hmmm te ingewikkeld...
De regexp kan er uit, dat zie ik in... ;)
Om bijvoorbeeld twee elementen te creëren en die toe te voegen kan ik nu het volgende doen...
JavaScript:
1
2
3
img = element.build("img", 'src="http://kaydies.com/images/kay_boom_thumb.jpg" selected id="test" class="test abc" alt="foto van kaydie"');
par = element.build("p","","Hier een stukje tekst");
element.add(par,img,"before")

@crisp
Goh werkt dat :? , kan dat hier zo niet testen, 'k draai geen Windows ;) Ik weet wel dat het in Firefox, Opera en Safari goed werkt... (text/html en application/xhtml+xml).

'k ga nog even sleutelen...

[ Voor 4% gewijzigd door kaydie op 28-08-2006 22:42 ]


  • Victor
  • Registratie: November 2003
  • Niet online
Ik zie dat mijn voorbeeld oa. geen img elementen ondersteund, even een kleine update (tevens met wat meer gangbare naamgeving voor variabelen, en commentaar):
JavaScript:
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
function domNodeBuilder(domNode) {
    // Als er geen nodeName is opgegeven, laat dan maar zitten.
    if (!domNode.nodeName) {
        return false;
    }

    // Maak een nieuw element.
    var _newElement = document.createElement(domNode.nodeName);

    // Is er content opgegeven? Is het een string? Dan een nieuwe textNode aanmaken en toevoegen. Is het een object? Dan direct als child toevoegen.
    if (domNode.contents) {
        if (typeof domNode.contents == "string") {
            _newElement.appendChild(document.createTextNode(domNode.contents));
        } else if (typeof domObject.contents == "object") {
            _newElement.appendChild(domNode.contents);
        }
    }

    // Zijn er attributen opgegeven?
    if (domNode.attributes) {
        // IE wil "className", de rest wil "class". Geef "className" op en "class" wordt automagisch toegevoegd met dezelfde waarde.
        if (domNode.attributes["className"]) {
            domNode.attributes["class"] = domNode.attributes["className"];
        }

        // Loop door alle attributen, en zet deze op het element.
        for (var _attribute in domNode.attributes) {
            _newElement.setAttribute(_attribute, domNode.attributes[_attribute]);
        }
    }

    // Geef het resultaat terug.
    return _newElement;
}


En om nu een plaatje toe te voegen aan de body, zou je het volgende doen:
JavaScript:
1
2
3
4
5
6
7
document.getElementsByTagName("body")[0].appendChild(domNodeBuilder({
    nodeName   : "img",
    attributes : {
        src : "afbeelding.jpg",
        alt : "Foo is good for you!"
    }
}));

  • kaydie
  • Registratie: Juni 2006
  • Laatst online: 06-01-2022
Bedankt voor de moeite King_Louie!
hier kan ik zeker wat mee!
Pagina: 1