Toon posts:

[js] discussie is dit een goede manier van objectwrapping?

Pagina: 1
Acties:

Verwijderd

Topicstarter
ok, d'r is al eens wat discussie geweest over hoe je op een goede manier je eigen objecten kan connecten met het DOM. Daar heb ik nu het volgende op bedacht.

stel je hebt de volgende eigen objecten:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
function myNode() {
}

myNode.prototype.attachLayer = function(obj) {
  obj._wrapper = this;
  this._layer = obj;
}

function iets() {
}

iets.prototype = new myNode();

die wil je hangen aan het volgende stukje html dat je al in je body hebt staan:
HTML:
1
2
<div id="n001">element1</div>
<div id="n002">element2</div>

dan maak ik daarvoor de volgende functie:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function attachNode(nodeType,nodeId) {
  var newNode = new window[nodeType]();
  newNode.attachLayer(document.getElementById(nodeId);
  window[nodeId] = newNode;
}

// en die roep ik dan aan met:
function docLoad() {
  attachNode('iets','n001');
  attachNode('myNode','n002');
  alert(n002._layer.innerHTML);
}

onload = docLoad;


is dit een goede methode? ik vind hem wel aardig, maar ergens ook weer een beetje raar vanwege dat gestuntel met het window object.

verder heb ik nog niks bedacht om argumenten door te geven, iemand misschien hier ideeen over?

  • Clay
  • Registratie: Oktober 1999
  • Laatst online: 22-06 13:51

Clay

cookie erbij?

Het is denk ik eerst een kwestie van wat je doen wilt dan hoe je het aan gaat pakken. Wat wil je maken? Wil je echt een wrapper systeem bakken dat b.v. makkelijk tegen de DOM kan aanlullen? of ben je een wrapper aan het maken omdat je een wrapper wil maken? :)

PPK heeft er een artikel over geschreven (maken van libs, wrappers in het algemeen) met als hoofdnoot dat het fout is. De argumenten zijn dat je doorgaans met bestanden komt te zitten die achterlijk groot zijn, die je dan gebruikt voor kleine dingetjes. In totaal gebruik je dan nogal veel K's om een effect te berijken dat met weinig en specifieke code zonder wrappers of libs veel korter kan.
Ook haalt hij het "hoogmoed" argument erbij, dat je als developer durft te denken dat je iets beters kan bedenken dan de DOM (want die is toch ook goed) en zodoende weer een bak eigen objecten en properties introduceert waar mensen uit moeten zien te komen (mits het voor derden is dan)

Ik ben het dan deels met PPK eens, maar deels ook niet. Als je iets kleins maakt, of een korte wrapper weet te schrijven werkt dat volgens mij prima en makkelijk. Verder is de DOM wel leuk, maar korte code geeft het ook niet bepaald als je flink wat met elementen aan de gang gaat.

code:
1
2
3
4
var el = document.createElement('div');
var txt = document.createTextNode('hello world');
el.appendChild(txt);
document.body.appendChild(el);


vind ik toch behoorlijk lang eigenlijk (zonder innerHTML) b.v. Vergeleken met;

code:
1
2
var el = new Element('div');
el.write('hello world');


Met een wrapper is het nogal wat makkelijker om mee te werken als je dingen wil maken, en kan mits goed toegepast je code niet langer maken dan zonder. Het is immers een DOMwrapper, geen XBrowser dhtml lib. Daar zit een wereld van verschil tussen. Verder geloof ik niet zo dat er echt legers mensen zijn die ueberhaupt met de DOM overweg kunnen, en diegenen die dat wel kunnen kunnen ook echt wel een ander systeem aanleren als dat moet of als ze dat zouden willen.

Hoe zou ik dan een wrapper maken? Ten eerste zou ik het nu ervan willen definieren. Iets ala:

Een wrapper (of domlib) bouwen die html elementen kan aanspreken of aanmaken of verwijderen uit een document, en attributen en css eigenschappen kan controleren.

dus new Element('div'); lijkt me heel zo gek niet dan. Daarbinnen laat je dan de createElement en appendChild afhandelen, en als je dat dan een beetje ala de DOM doet kan je ook elementen nesten, door je wrapper bv een subroutine te geven die een Element binnen zijn eigen element aanmaakt. Omdat die dan allemaal handles teruggeven heb je ook eigenlijk geen ID's meer nodig. Alleen het attachElement (of idd Node, zou ik iig eerder doen dan attachLayer) werkt dan nog met een id, en globale arrays met verwijzingen zijn in 1 keer overbodig :P (DOM doet het ook al niet)

En dan heb ik eigenlijk nog geen regel code geschreven. Maar het idee lijkt me wel duidelijk. Ik snap trouwens eigenlijk niet wat je met myNode, iets en attachNode probeert. De wrapper om een DOM element is 1 ding, maar een component of iets dergelijks wat je gaat bouwen hoeft toch niet over te erven van de wrapper class? Die hoeft alleen maar het verwezen element als property te hebben, met een rits functies om deze te aan te kunnen spreken?

Ik zou het iig vooral simpel houden. OO constructies en overerving etc. zijn heel tof om mee te spelen, maar als je ze niet nodig hebt moet je ze echt niet gebruiken, beter kort, overzichtelijk en duidelijk dan lang, obscuur en vaag. Zo moet je inderdaad dus niet proberen javascript te laten werken als Java oid.

[ Voor 4% gewijzigd door Clay op 28-08-2003 20:50 ]

Instagram | Flickr | "Let my music become battle cries" - Frédéric Chopin


  • Woudloper
  • Registratie: November 2001
  • Niet online

Woudloper

« - _ - »

+1 voor Clay. Erg goed stuk en een goede analyse + onderbouwing van het stuk van PPK. Overigens hier de link naar het artikel. Leest wat makkelijk mocht iemand het willen nalezen...

Maar om nog naar de TS'er te reageren. Ik sluit mij geheel aan bij het punt van Clay. Waarom zou je het willen doen. Met andere woorden: wat is het doel van het bouwen van een wrapper?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 01:56
Ik vind het vrij dom om gelijk alle JavaScript libraries af te wijzen, ongeacht hun doel en kwaliteit. Ik kan me voorstellen, juist omdat (zoals Koch ook schrijft) verschillende browsers niet helemaal compatible met elkaar zijn, een goede JavaScript library (die een duidelijke interface aanbiedt en daarmee de incompatibiliteit tussen verschillende browsers weet weg te nemen) de ontwikkeltijd en de uiteindelijke kwaliteit van een website aanzienlijk kan bevorderen.

Zoals Koch namelijk ook zelf zegt, is het ontzettend moeilijk om browser-onafhankelijke JavaScript-code te schrijven. Het lijkt me dan ook helemaal niet verkeerd als iemand anders dit moeilijke werk voor z'n rekening neemt, waardoor jij, als gebruiker van de library, je kan concentreren op simpele JavaScript code, die je lokaal op een enkele browser kunt testen, waarna je de garantie hebt dat het deel dat door de library afgehandeld wordt ook op andere browsers correct uitgevoerd wordt.

Eigenlijk pleit Koch ervoor dat iedere JavaScript-programmeur de problemen van portabiliteit maar weer opnieuw moeten uitvinden, oplossen en testen. Dat is in veel situaties simpelweg niet mogelijk. Koch schrijft: "I want a clear view of the browsers my script runs in, of their problems and quirks"; maar ik betwijfel of hij alle quirks van alle browsers kent. Het idee van een library is dat je er functionaliteit van verschillende personen met verschillende ervaringen in bundelt en daarmee een complete, consistente programmeerinterface levert.

Ik richt me in dit bericht vooral op argumenten van portabiliteit, wat het belangrijkste voordeel van een interface is die abstraheert van de browser-specifieke afhandeling van gewenste functionaliteit. De argumenten voor het ontwikkelen van zo'n library zijn hetzelfde als voor libraries als DirectX of ODBC; in het algemeen is abstraheren van specifieke situaties en het aanbieden van universele interfaces juist een goed streven. Het lijkt er op dat Koch dat met de rest van de wereld oneens is, of toch tenminste aan dit punt voorbij gaat. Het lijkt me sterk dat hij dat echt zo bedoeld heeft en mocht dat wel zo zijn, dan kan ik zijn punt nauwelijks serieus nemen.

Verder vind ik het enige praktische argument dat Koch te berde brengt niet zo sterk; library code zou te groot zijn, soms wel 40 kilobyte groot! Nu is 40 kilobyte niet weinig, dat geef ik zo toe, maar het is wel content die praktisch altijd en overal gecached kan worden. Verder is 40 kilobyte vergeleken met overige content ook weer niet zo heel erg groot; de banner die ik nu in beeld zie, bijvoorbeeld, is ook al 32 kilobyte groot. Onder deze textarea staan een stuk of 30 smileys die gemiddeld groter zijn dan 1 kilobyte. Toch is GoT niet echt belachelijk traag! Daarbij vemeldt Koch niet dat met een geschikte library de applicatiecode veel beknopter kan worden (er hoeft immers geen browseronderscheid meer gemaakt te worden) waardoor effectief de code size wel eens omlaag zou kunnen gaan.

[ Voor 20% gewijzigd door Soultaker op 29-08-2003 01:10 ]


  • Clay
  • Registratie: Oktober 1999
  • Laatst online: 22-06 13:51

Clay

cookie erbij?

Klopt idd. Overigens is 40 K voor een banner te groot. De banners waar ik me bezig heb moeten houden mochten nooit groter zijn dan 12 tot 18 K, afhankelijk van de afmetingen.

Ik wil trouwens ook even het verschil tussen een DOM library en dhtml library benadrukken. De (imo achterhaalde) dhtml library pakt inderdaad de grote verschillen tussen browsers (document.all, document.layers, document.getEle...) en bouwt hier een algemene voor alles werkende wrapper omheen. Dat was heel nuttig, en moet soms helaas nog steeds gebruikt worden als b.v. een klant voet bij stuk houdt.
Dhtml libraries worden alleen doorgaans erg groot. Omdat je aan de hand van een browsercheck door de hele lib heen bergen met ifjes hebt staan om op elke browser anders te reageren en daarvoor ook steeds vershcillende code moet schrijven krijg je hoe dan ook een verhoudingsgewijs groot bestand. Zo was ik er al best trots op dat Beehive I iets van 15K was.

Een DOM library/wrapper hoeft geen browsercheck te hebben, omdat de oude interpretaties gewoon niet gebruikt worden. Het dient enkel om de DOM op een kortere en snellere manier aan te spreken, en dat kan dan met veel minder code.

Beehive II werkt b.v. ruwweg zo:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
document.createObject = function(type, attr, css) {
    var ele = document.createElement(type);
    pushProperties(attr, ele);
    pushProperties(css, ele.style);
    document.body.appendChild(ele);
}

function pushProperties(list, target) {
    for(var i in list) {
        try {
            target[i] = list[i];
        } catch(e) {}
    }
}

window.onload = function() {
    document.createObject('div', {innerHTML:'hoi'}, {color:'red'});
}


En dan OO om ook te kunnen nesten. Dat is wel ff een stukje korten dan een browsercheck met X interpretaties om een element op je scherm te kunnen krijgen. En dan zie ik eigenlijk alleen maar voordelen. Het is klein, makkelijk, snel. Het enige punt is dat je er even mee om moet leren gaan als je het kiest te gebruiken.

Instagram | Flickr | "Let my music become battle cries" - Frédéric Chopin


Verwijderd

Topicstarter
Wat ik dus wil doen is een domlibrary. Daar zit wel wat support in voor verschillende browser nukkigheden, maar minimaal. Waar het om gaat is dat actieve elementen in mijn pagina een hele reeks acties kunnen uitvoeren die specifiek voor dat element zijn. Ook zijn er wat acties die voor alle elementen gelden (setten van css bijvoorbeeld). Dit schreeuwt imho om een oo oplossing. Dus bouw je die actieve elementen als objecten.

Ik wil echter niet heel het element (zeg maar even een div) dynamisch genereren, als de browser namelijk onder de categorie "not supported" vallen bouw ik die hele objectboom gewoon niet. Ik wil dan wel wat content hebben staan, alleen kan je er dan niet zo gek veel mee (of worden grafisch minder interessante oplossingen aangeboden).

De html van de elementen staat dus in m'n document en onload worden er objecten gegenereerd die die elementen vertegenwoordigen. Om een voorbeeld aan te halen: ik heb een tabelweergave waarin je kolommen kan selecteren, rijen kan selecteren, sorteren, verwijderen etc. De primaire content staat dus in html. Alle methods staan in het object wat ik onload genereer. Deze twee moeten dus aan elkaar gekoppeld worden en dat wil ik nou bereiken met bovenstaande code

Dit is natuurlijk ook maar een voorbeeld. Maar in principe zou dit kunnen voor alle situaties waar je een bestaand html (dom) element hebt waar content in staat en die wil je koppelen aan een onload te genereren eigen object.
Pagina: 1