Avatar billede andreas13_fam Nybegynder
07. juni 2010 - 17:45 Der er 3 kommentarer og
1 løsning

DOM framework

Hej

Jeg vil forsøge at lave mit eget framework der skal gøre det letter at lave DOM elementer i stedet for at skrive document.createElement('div') hele tiden.

Dog kan ikke ikke få noget til at virke.
Følende er mit test miljø, resultat skulle gerne være at de 2 første er rød, dernæst en grøn, og tilsidst en blå.


<!DOCTYPE html>
<html>
    <head>
        <title>Framework test</title>
        <script type="text/javascript">
            (function (window) {
            var EVA = {};
           
            EVA.DOM = function( selector ) {
                return new EVA.DOM.fn.init( selector );
                   
            };
           
            EVA.DOM.fn = EVA.DOM.prototype = {
                selector: "",
                length: 0,
                nodes : [],
           
                init : function (selector) {
                    this.selector = selector;
                    if (typeof selector === 'object') {
                        nodes.push(selector);
                        this.length++;
                    } else {
                        var nodes = document.querySelectorAll(selector);
                        if (typeof nodes === 'object' || typeof nodes === 'function') {                       
                            for (var i=0;i<nodes.length;i++) {
                                this.nodes.push(nodes[i]);
                                this.length++;
                            }
                        }
                    }
                           
                    return this;
                },
           
                run : function (func,parms) {
                    for (var i=0;i<this.length;i++) {
                        func(this.nodes[i],parms,this);
                    }
                    return this;
                }
            };
           
           
            // installere funktioner i construktoren
            EVA.DOM.fn.init.prototype = EVA.DOM.fn;
           
            // Sender EVA ud til window.
            window.EVA = EVA;
           
            })(window);
        </script>
        <style type="text/css">
            div {
                float: left;
                width: 200px;
                height: 200px;
                margin: 5px;
                border: 20px solid #AAA;
            }
        </style>
    </head>
    <body>
        <div id="foo1"></div>
        <div id="foo2"></div>
        <div id="bar1"></div>
        <div id="bar2"></div>
        <script type="text/javascript">
            EVA.DOM('#foo1, #foo2').run(function (element) {
                element.style.backgroundColor = '#F00';
            });
           
            EVA.DOM('#bar1').run(function (element) {
                element.style.backgroundColor = '#0F0';
            });
           
            EVA.DOM('#bar2').run(function (element) {
                element.style.backgroundColor = '#00F';
            });
        </script>
    </body>
</html>
Avatar billede intenz Novice
07. juni 2010 - 20:59 #1
Sejt nok script du har fået lavet. Din fejl ligger i, at 'nodes' ikke bliver tømt hver gang du laver et nyt objekt (men length gør). Der er sikkert en god forklaring på hvorfår, men jeg kan ikke lige se årsagen.

Men du kan rette den ved at indsætte:
this.nodes = [];

Efter:
this.selector = selector;

Udover det er du igang med at opfinde funktionalitet som allerede eksisterer. Det eksempel du skriv/har lavet kan opnås relativt simpelt med f.eks. jquery. Men det er cool nok det du har lavet, så hvis du har lyst så forsæt da endelig :)

Her er et jquery eksempel, der gør det samme som dit script (og lidt mere).


<html>
<head><title>jQuery test</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
$(document).ready(function () {

    // lav element og sæt class
    var div = $("<div />").addClass("test");

    // lav flere af samme, med forskelligt ID og sæt i body
    div.clone().attr("id", "foo1").appendTo("body");
    div.clone().attr("id", "foo2").appendTo("body");
    div.clone().attr("id", "bar1").appendTo("body");
    div.attr("id", "bar2").appendTo("body");

    // opdater baggrund
    $("#foo1, #foo2").css("background-color", "#F00");
    $("#bar1").css("background-color", "#0F0");
    $("#bar2").css("background-color", "#00F");

});
</script>

<style type="text/css">
.test {
    float: left;
    width: 200px;
    height: 200px;
    margin: 5px;
    border: 20px solid #AAA;
}
</style>
</head>
<body>
</body>
</html>
Avatar billede andreas13_fam Nybegynder
08. juni 2010 - 11:32 #2
Ja jeg har faktisk set en hel del på jQuery, jeg har tilmed læst en stor del af frameworket, jeg kan bare ikke rigtig gøre op med mig selv om det er noget jeg skal benytte.

Jeg har i mellemtiden forsøgt mig jQuery, og må da sige at det gør mange ting letter, der er dog også nogle aspekter hvor der ikke bliver gjort brug af DOM men innerHTML. Det er ikke fordi jeg har noget imod innerHTML, men jeg syntes det har det med at give nogle problemer for mig fordi jeg ikke kan se nogen logik i at HTML skal behandles som tekst stænge.

Hvis  nogen skulle været interesseret så er her en udvidelse til mit "framework" med en sammenligning til jQuery.


<!DOCTYPE html>
<html>
    <head>
        <title>Framework test</title>
        <meta charset="utf-8">
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
        <script type="text/javascript">
            (function (window) {
            var EVA = {};
           
            EVA.DOM = function( selector ) {
                return new EVA.DOM.fn.init( selector );
                   
            };
           
            EVA.DOM.fn = EVA.DOM.prototype = {
                selector: "",
                length: 0,
                nodes : [],
           
                init : function (selector) {
                    this.selector = selector;
                    this.nodes = [];
                    this.length = 0;                   
                   
                    if (typeof selector === 'undefined') {
                        return this;
                    } else if (typeof selector === 'string') {
                        if (selector.match(/<[a-z]+>/)) {
                            return this.create(selector.replace('<','').replace('>',''));
                        }
                    }
                    return this.push(selector);
                },
               
                concat : function (arr) {
                    for (var i=0;i<arr.length;i++) {
                        this.nodes.push(arr[i]);
                        this.length++;
                    }
                   
                    return this;
                },
               
                push : function (selector) {
                    this.concat(this._select(selector));
                   
                    return this;
                },
               
                _select : function (selector) {
                    var i,s,nodes=[];
                   
                    if (typeof selector === 'string') {
                        selector = [selector];
                    }
                   
                    if (typeof selector === 'object' && selector instanceof Array) {
                        for (i=0;i<selector.length;i++) {
                            if (typeof selector[i] === 'string') {
                                selector[i] = document.querySelectorAll(selector[i]);
                                for (s=0;s<selector[i].length;s++) {
                                    nodes.push(selector[i][s]);
                                }
                            } else {
                                nodes.push(selector[i]);
                            }
                        }
                    }
                   
                    return nodes;
                },
           
                run : function (func,parms) {
                    for (var i=0;i<this.length;i++) {
                        func(this.nodes[i],parms,this);
                    }
                    return this;
                },
               
                create : function (element) {
                    this.nodes.push(document.createElement(element));
                    this.length++;
                   
                    return this;
                },
               
                attr : function (name, value) {
                    for (var i=0;i<this.length;i++) {
                        this.nodes[i].setAttribute(name,value);
                    }
                   
                    return this;
                },
               
                css : function (name, value) {
                    var o = {}, n, i;
                    if (typeof name === 'string') {
                            o[name] = value;
                        name = o;
                    }
                   
                    for (n in name) {
                        for (i=0;i<this.length;i++) {
                            if (typeof this.css.browserSupport[n] === 'function') {
                                this.css.browserSupport[n](this.nodes[i],name[n]);
                            } else {
                                this.nodes[i].style[n] = name[n];
                            }
                        }
                    }
                   
                    return this;
                },
               
                appendTo : function (selector) {
                    var nodes = this._select(selector),i,s;
                    for (i=0;i<this.length;i++) {
                        for (s=0;s<nodes.length;s++) {
                            nodes[s].appendChild(this.nodes[i]);
                        }
                    }
                    return this;
                },
               
                text : function (text) {
                    for (i=0;i<this.length;i++) {
                        this.nodes[i].appendChild(document.createTextNode(text));
                    }
                    return this;
                },
               
                clear : function () {
                    for (i=0;i<this.length;i++) {
                        while (this.nodes[i].firstChild) {
                            this.nodes[i].removeChild(this.nodes[i].firstChild);
                        }
                    }
                    return this;
                },
            };
           
            EVA.DOM.fn.css.browserSupport = {
                float : function (ele,val) {
                    ele.style[document.all ? 'styleFloat' : 'cssFloat'] = val;
                }
            };
           
           
            // installere funktioner i construktoren
            EVA.DOM.fn.init.prototype = EVA.DOM.fn;
           
            // Sender EVA ud til window.
            window.EVA = EVA;
           
            })(window);
        </script>
        <style type="text/css">
            div.test {
                float: left;
                width: 200px;
                height: 200px;
                margin: 5px;
                border: 20px solid #AAA;
            }
        </style>
    </head>
    <body>
        <div id="foo1" class="test"></div>
        <div id="foo2" class="test"></div>
        <div id="bar1" class="test"></div>
        <div id="bar2" class="test"></div>
        <script type="text/javascript">
            EVA.DOM('#foo1, #foo2').run(function (element) {
                element.style.backgroundColor = '#F00';
            }).text('DOM modificeret rød').css('color','#FFF');
           
            var test = EVA.DOM('#bar1').run(function (element) {
                element.style.backgroundColor = '#0F0';
            }).text('DOM modificeret grøn');
           
            EVA.DOM('#bar2').run(function (element) {
                element.style.backgroundColor = '#00F';
            }).text('DOM modificeret blå').css('color','#FFF');
           
            test.push('#foo1').run(function (element) {
                element.style.backgroundColor = '#0F0';
            }).clear().text('DOM modificeret grøn');
           
            EVA.DOM('<div>').css({
                float : 'left',
                width : '200px',
                height : '200px',
                margin : '5px',
                border : '20px solid #AAA',
                backgroundColor : '#FF0'
            }).text('DOM indsat med EVA gul').appendTo('body');
           
            $('<div>')
                .css('float','left')
                .css('width','200px')
                .css('height','200px')
                .css('margin','5px')
                .css('border','20px solid #AAA')
                .css('background-color','#F0F')
                .text('indsat med jQuery lilla')
                .appendTo('body');
               
            $('<div>').css({
                float : 'left',
                width : '200px',
                height : '200px',
                margin : '5px',
                border : '20px solid #AAA',
                backgroundColor : '#0FF'
            }).text('indsat med jQuery lysblå').appendTo('body');
        </script>
    </body>
</html>
Avatar billede intenz Novice
08. juni 2010 - 12:04 #3
Fordelen ved jQuery er vel primært at man ikke behøver at udvikle frameworket, og det samtidigt ordner cross-browser problemerne med javascript.

Udover det kan man også benytte det hav af plugins der bliver lavet af 3-parts udviklere. Og så er jQuery efterhånden ved at blive et standard framework på mange sites, hvilket gør kendskab til det en fordel i forhold til jobs.

Men som sagt er det imponerende nok det du har lavet, men spørgsmålet ender vel med, at man skal overveje om man vil bruge tiden på at udvikle frameworket, eller på at bruge frameworket. Når man laver sig eget kommer man hurtigt til at bruge tiden på at udvikle ny funktionalitet til det, som måske findes 'out of the box' i jQuery eller gennem plugins til det.
Avatar billede andreas13_fam Nybegynder
08. juni 2010 - 13:07 #4
Du læser jo mine tanker
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester