[js] classes, eventhandlers en this.*

Pagina: 1
Acties:

  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
Ik ben een class aan het bouwen die onder andere wat knopjes spawned welke bepaalde functies van die class moeten aanroepen.

Ik heb bijvoorbeeld:

De constructor van class die een divje maakt, met daarin een button, Deze button moet de functie close() can dat object aanroepen.

Nu kan ik gewoon met addEventListener een functie aan die knop binden (bijvoorbeeld this.close();, maar die functie weet dan helemaal niet welk object "this" eigenlijk is, en kan dus ook niet veel doen.

Hoe los ik dit op?
Ik kan natuurlijk de event afvangen en dan de dom oplopen tot ik bekend ID tegenkom welke ik aan een array objects kan knopen, maar dat lijkt me wel een heel erg ranzige oplossing.

openkat.nl al gezien?


  • gvdh81
  • Registratie: Juli 2001
  • Laatst online: 22-01 09:01

gvdh81

To got or not to got..

je kunt zoiets doen:

pseudo code:
code:
1
2
3
4
5
6
7
8
object {
  toon() {
    var _this = this;
  }
  hide() {
    ....
  }
}


en dan kun je _this gebruiken in die functie. Zo los ik het op ;) Dan heb je de this (alszijnde het object) en kun je dus _this.hide(); aanroepen.

  • Amras
  • Registratie: Januari 2003
  • Laatst online: 01-10-2025
Misschien iets duidelijker zo:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function SomeClass()
{
    this.name = 'SomeClass';
    this.div = document.createElement('div');
    ...

    var self = this;
    this.div.onclick = function()
    {
        alert(self.name); // geeft: SomeClass
    }

    ...
}

Verwijderd

Ik zou alleen de function niet er op deze manier aan hangen, want dan ga je lekken krijgen. Dus even een global function eraan hangen die de events oppakt. :)

Verwijderd

Van die regel met var self = this; moet ik al huiveren. Er is echt geen enkele goede reden te bedenken waarom je dat zou willen doen.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:42

crisp

Devver

Pixelated

Nu kan ik gewoon met addEventListener een functie aan die knop binden (bijvoorbeeld this.close();, maar die functie weet dan helemaal niet welk object "this" eigenlijk is, en kan dus ook niet veel doen.
:?
HTML:
1
2
3
4
5
6
7
8
9
10
11
<div id="foo">divje</div>
<script type="text/javascript">

document.getElementById('foo').addEventListener('click', myFunc, false);

function myFunc(e)
{
    alert(this.getAttribute('id'));
}

</script>

Kortom: die functie weet dondersgoed wat 'this' is; namelijk het HTML-object waarop het event werd uitgevoerd :P (niet wat je bedoelde, maar ter illustratie ;) )
Verwijderd schreef op zaterdag 18 februari 2006 @ 23:02:
Van die regel met var self = this; moet ik al huiveren. Er is echt geen enkele goede reden te bedenken waarom je dat zou willen doen.
Op zich is dat helemaal niet gek omdat je daarmee een referentie in een var stopt ('this' kan je niet als variabele gebruiken uiteraard) waarmee je een closure kan creëeren :) (wel een recept voor memory-leaks in IE als er DOM-referenties mee gemoeit zijn)

[ Voor 47% gewijzigd door crisp op 18-02-2006 23:26 ]

Intentionally left blank


  • Amras
  • Registratie: Januari 2003
  • Laatst online: 01-10-2025
Verwijderd schreef op zaterdag 18 februari 2006 @ 23:02:
Van die regel met var self = this; moet ik al huiveren. Er is echt geen enkele goede reden te bedenken waarom je dat zou willen doen.
Hoe wil je dan bij een 'koppeling' van een html element en een JS object de attributen van het JS object benaderen in een eventhandler van het html element? Dat lijkt me iets wat je zou willen doen.

Je kan ook het html element een id geven wat je ook aan het JS object toekent en ze zo dan samen 'registreren' in een globaal array ofzo. Dan moet je alleen in de eventhandler eerst het JS object uit dat array vissen aan de hand van het id van het html element.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:42

crisp

Devver

Pixelated

Je kan de referentie naar je JS-object ook gewoon in de DOM-space van je element stoppen:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function SomeClass()
{
    this.name = 'SomeClass';
    this.div = document.createElement('div');
    this.div.appendChild(document.createTextNode('foo'));
    document.body.appendChild(this.div);

    this.div.__classref = this;
    this.div.onclick = function()
    {
        alert(this.__classref.name); // geeft: SomeClass
    }
}

var foo = new SomeClass();

Intentionally left blank


Verwijderd

In bepaalde gevallen moet je gewoon scopen.

var self = this;
window.setTimeout(function(){self.method()},35);

Als je dat niet zou doen, wordt method op je window object uitgevoerd.

[ Voor 88% gewijzigd door Verwijderd op 18-02-2006 23:50 ]


  • Amras
  • Registratie: Januari 2003
  • Laatst online: 01-10-2025
crisp schreef op zaterdag 18 februari 2006 @ 23:31:
Je kan de referentie naar je JS-object ook gewoon in de DOM-space van je element stoppen:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function SomeClass()
{
    this.name = 'SomeClass';
    this.div = document.createElement('div');
    this.div.appendChild(document.createTextNode('foo'));
    document.body.appendChild(this.div);

    this.div.__classref = this;
    this.div.onclick = function()
    {
        alert(this.__classref.name); // geeft: SomeClass
    }
}

var foo = new SomeClass();
Kan inderdaad, maar als ik het goed heb lekt dit geheugen in IE (kan ik mis hebben, maar zoiets staat me bij). Persoonlijk zou ik kiezen voor de var self = this constructie.

Verwijderd

Amras schreef op zondag 19 februari 2006 @ 00:31:
[...]

Kan inderdaad, maar als ik het goed heb lekt dit geheugen in IE (kan ik mis hebben, maar zoiets staat me bij). Persoonlijk zou ik kiezen voor de var self = this constructie.
Ja klopt, elke referentie tussen de dom en js lekt in IE geheugen en zal handmatig moeten worden opgeruimd. Het zijn in IE ook twee gescheiden "systemen" met hun eigen garbage collectors, en dat is oa onderdeel van de oorzaak.

Ik kies zelf eigenlijk ook liever voor de scope in een var, ik houdt er zelf niet zo van om mijn dom te voorzien van allerlei scopes die van toepassing zijn op objecten en niet op elementen. :)

[ Voor 17% gewijzigd door Verwijderd op 19-02-2006 00:36 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:42

crisp

Devver

Pixelated

No, niet elke referentie tussen DOM en JS lekt geheugen in IE, anders zou je elke event-handler ook moeten opruimen op onunload. Het zijn voornamelijk circular references die lekken, en geneste references - alles wat de garbage collector niet kan opruimen doordat 'ie niet kan zien wat de references zijn en dat gecombineerd met het feit dat DOM-references COM-objecten zijn in IE en niet gezien worden door de JS garbage collector.

(mijn voorbeeld lekt wel overigens in IE, maar de self = this constructie ook :P )

[ Voor 107% gewijzigd door crisp op 19-02-2006 01:19 ]

Intentionally left blank


  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Je krijgt toch gewoon een referentie naar het object meeestuurd in de target property van het event object? Waarom gebruik je die niet in de close() functie?

Ik ontken het bestaan van IE.


  • Clay
  • Registratie: Oktober 1999
  • Laatst online: 18-02 12:13

Clay

cookie erbij?

event.target of event.srcElement bevatten idd het element waar je muis op dat moment zat, maar als je het event bv op de body zet, en die dan door een div gefired wordt, krijg je daarin toch echt die div terug en niet de body.

Wbt die self = this constructie of een referentie aan een htmlElement hangen zit ik een beetje in het midden. Het eerste is misschien niet superelegant (hoewel het in feite hetzelfde is als een globale variabele ergens binnen een functie gebruiken) maar het 2e moet ook maar net kunnen; wie zegt er dat je instantie altijd ergens - en door 1 nb - element vertegenwoordigd wordt?

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


Verwijderd

crisp schreef op zondag 19 februari 2006 @ 00:43:
No, niet elke referentie tussen DOM en JS lekt geheugen in IE, anders zou je elke event-handler ook moeten opruimen op onunload.
Je hebt inderdaad gelijk, het blijft een lastig geheel die issues, wat wel en wat niet lekt en in welke constructie wel en welke constructie niet. Zodra je een js object refereert met een dom object ga je het wel krijgen omdat beide garbage collectors van elkaar niet weten of de referenties nog bestaan.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function test(){
    this.el = document.createElement('div');
    document.body.appendChild(this.el);
    // onderstaande regel lekt
    this.el.ref = this;
    
    var self = this;
    this.ev = function(e){self.doeiets(e)};
    if(document.addEventListener) { 
        document.addEventListener("mousemove",this.ev,false );
    }else if(document.attachEvent){
        document.attachEvent("onmousemove",this.ev);
    }
    
    this.el.onclick = self.doeiets;
}

test.prototype.doeiets = function(e){
    window.status = 'iets gedaan';
}
new test();

[ Voor 14% gewijzigd door Verwijderd op 19-02-2006 18:06 ]


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
hmm, okey, had niet zo veel reacties verwacht (en kon op m'n pda alleen mijn post lezen vannacht, (kon wel zien dat er 14 posts waren , erg frustrerend :P)

Ik denk dat ik inderdaad met de var self=this; constructie verder ga,
Als ik het goed begrijp moet ik alleen netjes de eventhandlers opruimen als ik het object weggooi?, dat moet lukken met removeEventListener lijkt me.

* killercow pakt alvast een dwijl. :)

openkat.nl al gezien?


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
hmm, toch niet helemaal wat ik zocht :P

Het werkt namenlijk niet goed.
Als ik self binnen de class defineer, kan ik er niet bij van buiten de class (de functie),
Als ik de self var globaal defineer, kan ik maar een window aanspreken.
Als ik de self var een array van alle window objecten laat zijn heb ik geen idee welke ik moet hebben.

Is er geen manier om de functie die aangroepen wordt via een eventhandler binnen de scope van de bindende object te executen?

(en if so, waarom is dat nog niet toegevoegd aan de standaart?, want dit lijkt mij iig een redelijk stomme fout in het ontwerp van een taal als javascript.

openkat.nl al gezien?


Verwijderd

Ik volg totaal niet wat je probeert te doen :)

Even quick n dirty zonder addeventlistener/attachevent, 3 manieren. Waarbij de laatste twee een lek creeeren en dus handmatig moet worden opgeruimd.

function foo(){
this.el = document.createElement('div');

this.el.onclick = function(){alert(this.tagName)};

var self = this;
this.el.ondblclick = function(){alert(self.constructor)};

this.el.objref = this;
this.el.onmouseout = function(){alert(this.objref.constructor)};
}

[ Voor 14% gewijzigd door Verwijderd op 20-02-2006 21:11 ]


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
En kan het niet zo?
code:
1
2
3
4
5
6
7
8
9
function foo(){
this.el = document.createElement('div');
this.name='woei';
this.el = document.createElement('div');
this.el.addEventListener('click',this.test,false);
}
function test(){
 alert(this.name);
}


Ik wil de tet functie ook van buiten de class aanroepen met myclass.test();
Maar dus ook van binnen, op dynamisch gegenereerde objecten.
onclick= setten enzo is A, niet echt dom2, en B, waarom?

openkat.nl al gezien?


Verwijderd

Op het moment dat je het onclick event uitvoert ga je het volgende uitvoeren:

this.test(); en op het moment dat je het onclick event afvuurt staat this gelijk aan je element. Het is hetzelfde als

<div onclick="this.test()"></div>

En dat is wat er bij jouw fout gaat. Kortom, je moet of gaan scopen, of een referentie naar het object aan je element hangen, of een stack bijhouden van fysieke id's van elementen en bij onclick het juiste object pakken uit je stack.

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
32
33
34
35
36
37
38
39
function foo(){
  this.el = document.createElement('div');
  this.el.id = 'mydiv';
  this.el.obj = this; // deze regel lekt
  this.el.onclick = function(){this.obj.test()};
}
foo.prototype.test = function(){
  alert(this.el.id);
}

function foo(){
  this.el = document.createElement('div');
  this.el.id = 'mydiv';
  var self = this;
  this.el.onclick = function(){alert(self.test()};
}
foo.prototype.test = function(){
  alert(this.el.id);
}

var instances = [];
function foo(){
   this.el = document.createElement('div');
   this.el.id = 'mydiv';
   instances.push(this);
   this.el.onclick = function(){getInstance(this).test()};
}
foo.prototype.test = function(){
  alert(this.el.id);
}

function getInstance(el){
  var i = instances.length;while(i--){
     if(instances[i].el.id == el.id){
       return instances[i];
     }
  }

}

[ Voor 102% gewijzigd door Verwijderd op 20-02-2006 22:14 ]


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
Ja ik snap wat er mis gaat in mijn code, maar bovenstaande oplossing zijn allemaal behoorlijk ranzig imho.

ik snap dat de events buiten het object aangeroepen worden enzo.

als het niet anders kan, tjah so be it, maar dan nog.. zo'n vreemde feature is het toch niet om, of maak ik nu echt een denkfout.

openkat.nl al gezien?


Verwijderd

killercow schreef op maandag 20 februari 2006 @ 22:28:
Ja ik snap wat er mis gaat in mijn code, maar bovenstaande oplossing zijn allemaal behoorlijk ranzig imho.

ik snap dat de events buiten het object aangeroepen worden enzo.

als het niet anders kan, tjah so be it, maar dan nog.. zo'n vreemde feature is het toch niet om, of maak ik nu echt een denkfout.
Als dat zou werken, hoe zou je dan een referentie naar je element moeten krijgen? Het is of het een of het ander ;)

  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
tjah, ik pik een referentie naar m'n element altijd op dmv het event object, dat ik idd als enige argument krijg.

Als je echter functies binnen een class aanroept, (of dat nu via eventHandlers of niet gaat) zou niet uit moeten maken imho, maar oke, volgens mij werk jullie voorbeeld nu inderdaad wel goed in mijn code.

openkat.nl al gezien?


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:42

crisp

Devver

Pixelated

killercow schreef op dinsdag 21 februari 2006 @ 09:03:
tjah, ik pik een referentie naar m'n element altijd op dmv het event object, dat ik idd als enige argument krijg.
Hoe doe je dat in IE dan? event.srcElement geeft immers niet het huidige element in bubbling phase...

Intentionally left blank


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
zo ongeveer:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (!event) var event = window.event; // make sure we actually get the event in IE

    if (event.target){ //w3c

        targ = event.target;

    } else if (event.srcElement) { // IE specific

        targ = event.srcElement;

    }

    if (targ.nodeType == 3){ // Safari bug correction, it selects the textrange instead of the object.

        targ = targ.parentNode;

    }


werkt prachtig.

openkat.nl al gezien?


Verwijderd

Voor elementen wel ja, niet voor instanties van javascript objecten :D

  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
nee, inderdaad. (dat zou inderdaad toch mooi zijn :))

[ Voor 4% gewijzigd door killercow op 21-02-2006 15:16 ]

openkat.nl al gezien?


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:42

crisp

Devver

Pixelated

killercow schreef op dinsdag 21 februari 2006 @ 14:32:
zo ongeveer:

[...]

werkt prachtig.
Dat vroeg ik niet; ik vroeg hoe je in bubbling-phase in IE opvraagt welk element op dat moment het event afhandelt - wat in het w3c event-model zeg maar je currentTarget is ;)

Het antwoord is natuurlijk: zonder een 'this' referentie in je handling-functie weet je dat niet in IE :P

Ter illustratie:
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
<a href="#" id="foo"><span>klik mij!</span></a>
<script type="text/javascript">

document.getElementById('foo').onclick = function(event)
{
    if (!event) event = window.event; // make sure we actually get the event in IE

    if (event.target)
    {
        //w3c
        targ = event.target;
    }
    else if (event.srcElement)
    {
        // IE specific
        targ = event.srcElement;
    }

    if (targ.nodeType == 3)
    {
        // Safari bug correction, it selects the textrange instead of the object.
        targ = targ.parentNode;
    }

    alert(targ.tagName); // SPAN
    alert(this.tagName); // A
}

</script>

oftewel: target/srcElement verwijst niet altijd naar het element dat je verwacht te krijgen cq nodig hebt ;)

[ Voor 54% gewijzigd door crisp op 21-02-2006 16:41 ]

Intentionally left blank


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
hmm,,

Ik Moet me echt meer in (hogere) javascript gaan verdiepen :P
Ik loop in mijn huidige project al een beetje tegen mijn beperkingen aan omdat ik hier nergens OO ontwikkeld heb, en nu bijvoorbeeld een 2e window wil openen.

Ik zit er aan te denken om alles te verbouwen naar een class, met eigen functies, maar tjah dan kom ik dus tientallen van dit soort problemen tegen.

Kijk hier voor de brij die ik nu heb gefabriceerd (en kies niet Low, want das stuk, en niet high, want das niet erg save for work pc's)
http://www.pc-gamers.com/webgamex/iso_js_coords.php :) (snowstorm is dr niks bij :))

Misschien kan ik iemand hier inspireren om mij te leren hoe ik met het opschonen van de code naar een hogere variant van javascript begin?

openkat.nl al gezien?


Verwijderd

Ik heb wel een aantal projecten beschikbaar, en met wat andere ben ik nog bezig. Verder zitten er op dit forum redelijk wat mensen met een javascript addiction en hebben ze vast ook nog wel wat.

http://www.mschopman.demon.nl/treeview_v1.6.5/treeview.html wordt geheel gegenereerd mbv dom methods en is oo opgezet.

Volgens dezelfde methodiek heb ik nog een menu voor je, met wat speciale features die ik eigenlijk in nog geen enkele ander component ben tegengekomen.

http://www.mschopman.demon.nl/menu/

En deze ben ik nog mee bezig, en is denk ik iets te complex om leerzaam te zijn en is nog niet af. Hier zit ook nog een issue in met een FireFox bug waarvan ik hoop dat ze die in 2.0 met de nieuwe redraw van tables gaan oplossen, ik doe nog niets aan de memleaks die je niet kunt omzeilen op een functionele manier, en ... zit nog vol met debugging en profiling zut want ik ben eigenlijk een heel domme ontwikkelaar die premature optimization toch wel leuk vind om te doen (en volgens mij Crisp ook :P )

http://www.mschopman.demon.nl/g/

[ Voor 6% gewijzigd door Verwijderd op 21-02-2006 20:53 ]


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
Die treeview ziet er inderdaad goed uit, ik ben zelf ook wel erg gecharmeerd van css oplossingen maar daar kun je tegenwoordig toch een boel dnigen nog niet mee doen.

Dat menu is ook goed leesbaar, wel ver uitgediept, classes voor elk voorkomend element type, ik had hier waarschijnlijk gewoon arrays voor gebruikt (iig voor de buttons dan enzo), schrijven van zoiets is andere koek natuurlijk.

(had je mijn code ook een beetje kunnen bekijken?, ik moet nodig eens een beetje refactoren denk ik)

Dat er hier op GOT een hele kudde JS gekken rond loopt weet ik, en ik kan zelf ook voldoende js om de meeste problemen handig op te lossen, maar juist bij een bijna volledig client side verhaal als m'n isometrische engine loop ik een beetje tegen mijn beperkingen in JS aan,

Ik zie jouw bjivoorbeeld heel veel prototypen, wat ik zelf nog nooit gedaan heb, snap wel wat het doet, maar zie niet echt in waarom.
Statements als create: zijn me nog onbekend, en ook trucjes toegepast in libs als moo.fx waarbij de options css style worden doorgegeven zijn me ook niet bekend.

(zeg wat kosten jullie hobby matig?, zou een paar zakken chips en kratje biet een gezellig weekend code sleutelen tot gevolg hebben? :P )

Ook mijn dhtml syntax highlighter is nog niet af gekomen (puur door geklooi met de codebase @ large):

http://boa.innerheight.com/parse/syntax_html/syntax_html.php

[ Voor 8% gewijzigd door killercow op 21-02-2006 21:17 ]

openkat.nl al gezien?


Verwijderd

killercow schreef op dinsdag 21 februari 2006 @ 21:12:
Dat menu is ook goed leesbaar, wel ver uitgediept, classes voor elk voorkomend element type, ik had hier waarschijnlijk gewoon arrays voor gebruikt (iig voor de buttons dan enzo), schrijven van zoiets is andere koek natuurlijk.
Het menu is eigenlijk ontstaan na een flapuit brainstorm met wat collega's. We wilden eigenlijk heel complexe interfaces gaan maken, maar hekelden allemaal het koppelen van functionaliteit aan commands. Elke command is dus een listener op zich zodat je niet meer in je applicatie elk specifieke commando moet beheren. Verder zit elk element in een groep, zodat de seperators ook automatisch worden beheerd.
... loop ik een beetje tegen mijn beperkingen in JS aan,
Die beperkingen maken het leuk om oplossingen te vinden voor problemen die je opeens op een heel andere wijze moet gaan oplossen. Javascript kauwt je eigenlijk niet heel veel voor, en veel dingen die je wilt bereiken moet je echt gaan programmeren.
Ik zie jouw bjivoorbeeld heel veel prototypen, wat ik zelf nog nooit gedaan heb, snap wel wat het doet, maar zie niet echt in waarom.
Het scheelt je geheugen, voor iedere instantie hoeft een browser niet alle methods mee te kopieren en daarvoor geheugen te reserveren.
(zeg wat kosten jullie hobby matig?, zou een paar zakken chips en kratje biet een gezellig weekend code sleutelen tot gevolg hebben? :P )
Nooit uitgerekend, maar de tijd die ik erin steek kan nooit commercieel weggezet worden, daarvoor is het teveel. Daarnaast moet er ook nog tijd overblijven voor je vrouw .. die willen ook nog wel is wat aandacht opeisen :+

[ Voor 19% gewijzigd door Verwijderd op 21-02-2006 22:19 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:42

crisp

Devver

Pixelated

killercow schreef op dinsdag 21 februari 2006 @ 21:12:
(zeg wat kosten jullie hobby matig?, zou een paar zakken chips en kratje biet een gezellig weekend code sleutelen tot gevolg hebben? :P )
Normaliter wel, maar aangezien ik er een hobby bij heb komt daar nu niet zoveel meer van ;)

Ik ben iemand die houd van experimenteren en oplossingen vinden voor bepaalde problemen, niet zozeer van grote projecten - daar verzand ik vaak te snel in details en (zoals Gordijnstok al aangaf) in premature optimizations :P Ik ben teveel perfectionist daarvoor - given time komt er wel wat uit, maar dat kost vaak veel moeite, en andere uitdagingen lijden snel af...

Ik kom uit een omgeving van functionele programmeertalen en programmeer nog steeds veel op die manier, gemengt met wat OO waar dat zo uitkomt en/of praktisch is. Javascript leent zich prima daarvoor en voor veel dingen is een OO-aanpak vaak ook helemaal niet echt noodzakelijk - meer een kwestie van smaak.

DHTML lemmings was natuurlijk wel een groot project waar ik toen (nu alweer een paar jaar geleden) toch een hele truukendoos heb moeten openen en waar ik zelf ook veel van geleerd heb. Ik ben daarna zelfs nog begonnen aan een nieuwe engine waarbij ik gebruik maakte van bitmasks voor de grid (wat flexibeler was en sneller), maar ik ben daar - mede ook door het hele Brein-gedoe - nooit meer mee verder gegaan...

Laatste privé-project is CrispyPaint - een GIF-implementatie in javascript, grotendeels geschreven tijdens een Tnet crew-lan - maar ook dat ligt nu een beetje stil. Het is voornamelijk de interface die nog afgemaakt moet worden, maar de uitdaging lag meer in het doorgronden van compressie-technieken en het werken met binary files in javascript :)

Ik loop eigenlijk niet veel tegen beperkingen van javascript zelf aan (of mijn kennis ervan) maar destemeer tegen bugs en tekortkomingen van implementaties :P

[ Voor 5% gewijzigd door crisp op 21-02-2006 23:42 ]

Intentionally left blank


Verwijderd

crisp schreef op dinsdag 21 februari 2006 @ 23:40:
Ik loop eigenlijk niet veel tegen beperkingen van javascript zelf aan (of mijn kennis ervan) maar destemeer tegen bugs en tekortkomingen van implementaties :P
Ben ik het absoluut mee eens. Waar ik persoonlijk tegenop loop is de beperkte snelheid van dom in IE, die in FF al beter is en in Opera meesterlijk, en waar je snel neigt om een oplossing te kiezen met innerHTML maar waarbij je zelf weet dat je die oplossing niet wilt accepteren. Een component moet binnen milliseconden te genereren zijn, want luttele vertragingen worden door een gebruiker heel snel opgemerkt. Vooral als je die componenten in een groter geheel gaat gebruiken dan wordt die performance gewoon erg belangrijk.

Het valt me zowiezo op dat veel wat ik ontwikkel tegen FireFox bugs aanloopt, en in zowel IE6, Opera 8, en Opera 9 zonder problemen werken (alhoewel beide versies van Opera nog wel een nasty bug hebben met betrekking tot style.cursor). Ik had eht er laatst nog met een bekende js ontwikkelaar over, zo slecht is IE6 nog niet. De curve om oplossingen te laten werken in IE6 is heel laag, omdat veel zaken gewoon direct goed werken. :)

Ik vind het echt nog steeds onbegrijpelijk dat Gecko problemen heeft met redraws in tables, als je ze dynamisch genereerd. Dat zijn echt van die zaken die tegenwoordig echt niet meer mogen voorkomen.

[ Voor 17% gewijzigd door Verwijderd op 22-02-2006 09:08 ]


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
Ik kom zelf inderdaad vaak tegen mijn beperkingen in kennis over JS vast te zitten, waardoor complexere problemen ineens een hele berg code funzige code nodig hebben. (vandaar dit topic), dat JS meer kan dan ik (vaak) nodig heb klopt, dat kun je ook wel zien aan de meesterwerkjes die anderen het internet op gooien.

innerHTML wordt intern toch gewoon alsnog omzet naar dom calls? , dat was mijn idee iig,
Ik ben zelf vooral server-side begonnen met het echt programmeer werk, programma's die uberhaupt niet halverwege met input te maken krijgen, maar gewoon linear van A naar B werken, dat levert ook nog wel eens een kronkeltje in mijn gewoontes op.

Ik zit zelf vooral tegen de render snelheid van de gecko en mshtml engine te hikken, maar ik hoop dat dat met nieuwe ontwikkelingen als SVG en Cairo een verbetering op komst is.

Vooral Transparancy van PNG afbeeldingen is bizar zwaar, zelfs als images onderling niet verschuiven. hopelijk kan ik dat met een transparant SVG plaatje wat verbeteren.

Crisp, Hobby's als kindjes houdt ik de komende jaren nog even op afstand :), woon net een jaartje samen :)

Opera is een hele mooie browser, en het valt mij altijd op hoe goed alles het eigenlijk gewoon doet als ik iets voor gecko gebouwd heb, en daarna ook maar eens een kijkje in opera neem.

openkat.nl al gezien?


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:42

crisp

Devver

Pixelated

killercow schreef op woensdag 22 februari 2006 @ 10:23:
Ik zit zelf vooral tegen de render snelheid van de gecko en mshtml engine te hikken, maar ik hoop dat dat met nieuwe ontwikkelingen als SVG en Cairo een verbetering op komst is.
Canvas (HTML5) is ook erg veelbelovend ;)

Intentionally left blank


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
Crisp:
Ja kan niet wachten :), lijkt me ook erg handig voor jouw crisp-paint (erg leuk btw)
heb wel contact met de cairo devvers, maar momenteel is het allemaal alleen nog maar langzamer :P

openkat.nl al gezien?


Verwijderd

crisp schreef op woensdag 22 februari 2006 @ 10:27:
[...]

Canvas (HTML5) is ook erg veelbelovend ;)
Maar daarvan zie ik eigenlijk alleen echt het voordeel bij oa grafische elementen dan een hele interface. Specifieke zaken zoals een grafische weergave van statistische gegevens (grafiek,piechart,etc).

Wellicht zaken zoals editing van photo's, maar verder ook niet. :)

  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
ik wilde in m'n isometrische engine het water gedeelte via een canvas (of 100 kleintjes) gaan tekenen, zodat ik per tile een zware transparante png kan ditchen.

openkat.nl al gezien?


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
ai caramba,

De oplossing van gordijnstok werkte wel aardig, Maaaar zodra de structuren wat lastiger worden en er honderden objecten en handlers binnen de matchende div zitten moet je niet alleen de hele dom afstropen naar matchende div's maar dat ook nog eens per objct instance herhalen.

Daarnaast moet je ook nog eens on-the-fly alle id's uniek houden wil je dat alles uberhaupt blijft werken.

Ik denk dat dat zo ongeveer de traagste oplossing is om waterdicht aan de juiste div te komen, en zo aan de juiste class instance.

Ik kom er niet uit, heb alle opties uit deze thread geprobeerd, en zelf uiteraard nog wat meuk geprobeerd, maar helaas.

Mijn probleem is als volgt:

Ik heb een class die een x aantal objecten aanmaakt.
Deze class heeft een x aantal functies en eigen vars.
De class geeft aan bijna elk object een event-handler welke een lokale var moet aanpassen/testen, of een lokale functie moet aanroepen.

Ik moet meerdere classes naast elkaar kunnen draaien, en dus de event-handlers aan de juiste class kunnen binden.
zou iemand hier nog wat licht op kunnen schijnen? (als het handig is kan er ook even naar de code - online - gekeken worden)

En meteen maar even een edit:
de code op deze pagina doet ongeveer wat ik wil, events horen nu weer gewoon bij hum parent object.

je kunt zelfs httpXML onreadystatehandlers enzo defineren die zo werken.
(al moet ik nog wel even een pool bedenken voor de connectie objectjes die er gemaakt worden)

[ Voor 13% gewijzigd door killercow op 05-04-2006 23:43 ]

openkat.nl al gezien?


Verwijderd

Dat moet geen probleem zijn, mijn treeview ding draait in produktie met 1000den objecten met elk hun eigen eventhandlers, etc. :)

Waar loop je vast?

  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
Ik had geen idee meer van welk object de door een event-handler uitgevoerde functies een member waren.

this. wees immers naar het geklikte html element, en niet meer naar het object wat de handler had gezet, of het element gespawnd had.

Anyway, dat is nu opgelost met het stukje code op de vergeten link. DOH!
hierbij alsnog de link.
http://erik.eae.net/archives/2005/02/10/22.26.03/

Ik snap alleen niet wat hij met deze zin bedoelt:
In the Bindows world we went a different route and added an extra parameter to the EventTarget interface to solve the most common case:

this.obj.addEventListener("foo", this.handleFoo, this);
Want dat doet helemaal niks bij mij.

Dus gebruik ik nu:
code:
1
2
3
4
5
6
7
function createDelegate(oObject, sMethodName) {
   return function () {
      return oObject[sMethodName].apply(oObject, arguments);
   };
}

this.obj.onfoo = createDelegate(this, "handleFoo");

[ Voor 5% gewijzigd door killercow op 06-04-2006 09:16 ]

openkat.nl al gezien?


Verwijderd

Ik zou de delegates approach van Erik zowiezo niet volgen. De kans dat je memory leaks krijgt is heel groot.

Jij geeft aan dat je niet weet bij welk object een event hoort. Maar wat ik niet volg is hoe je dat niet kan weten als je bijvoorbeeld iets doet als.

code:
1
2
3
4
5
6
7
8
9
10
11
12
function Car(){}
Car.prototype.init = function(){
   this.el = document.createElement('div');
   this.el.obj = this;
   this.el.onclick = function(){brake();};
}
Car.prototype.gas = function(){}
Car.prototype.brake = function(){}

function brake(){
  this.obj.brake();
}



of

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
function Car(){}
Car.prototype.init = function(){
   this.el = document.createElement('div');
   var _onclick = function(){this.brake()};

   if(window.addEventListener) { 
        this.el.addEventListener("click",_onclick,false);
   }else if(window.attachEvent){
        this.el.attachEvent("onclick",_onclick);
   }   
}
Car.prototype.gas = function(){}
Car.prototype.brake = function(){}

  • Clay
  • Registratie: Oktober 1999
  • Laatst online: 18-02 12:13

Clay

cookie erbij?

killercow schreef op donderdag 06 april 2006 @ 09:16:
Ik had geen idee meer van welk object de door een event-handler uitgevoerde functies een member waren.

this. wees immers naar het geklikte html element, en niet meer naar het object wat de handler had gezet, of het element gespawnd had.

Anyway, dat is nu opgelost met het stukje code op de vergeten link. DOH!
hierbij alsnog de link.
http://erik.eae.net/archives/2005/02/10/22.26.03/

Ik snap alleen niet wat hij met deze zin bedoelt:

[...]

Want dat doet helemaal niks bij mij.

Dus gebruik ik nu:
code:
1
2
3
4
5
6
7
function createDelegate(oObject, sMethodName) {
   return function () {
      return oObject[sMethodName].apply(oObject, arguments);
   };
}

this.obj.onfoo = createDelegate(this, "handleFoo");
Nou, met

code:
1
this.obj.addEventListener("foo", this.handleFoo, this);


wordt de function pointer / referentie naar handleFoo aan het foo event toegewezen. Dat werkt op zich wel, maar handleFoo gaat dan alsnog in window scope uitgevoerd worden, waar je dus niets aan hebt. Dit stukkie inderdaad niet-werkende voorbeeldcode dient dan ook alleen om te laten zien wat hij met die createDelegate fixt.

Overigens is die createDelegate wel een stuk eleganter,

code:
1
2
3
4
5
function createDelegate(oObject, sMethodName) {
   return function () {
      return oObject[sMethodName].apply(oObject, arguments);
   };
}


maar net als de self = this constructie vang je hiermee ook oObject met een even ranzige closure in een potentieel memoryleakdrama-scenario ;) Imo blijft het dus zaak de boel gewoon onunload op te ruimen.

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


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
hmm, tjah moeten mensen maar niet van m'n site weg-gaan :P

nee okey, das lame.
setTimeout wordt ook op het window object uitgevoerd, zou je zoiets ook daarvoor kunnen gebruiken, of zijn er nog andere delayed execute opties die geen eval vorm gebruiken?

openkat.nl al gezien?


  • b19a
  • Registratie: September 2002
  • Niet online
Zelf maak ik gebruik van de prototype javascript "library". Deze heeft een functie genaamd "bind", en werkt heel erg makkelijk in deze gevallen:
JavaScript:
1
htmlObj.addEventListener("click", this.close.bind(this), true~false);

Zodra de functie close wordt uitgevoerd heb je weer beschikking over de originele this!

Code van deze bind methode:
JavaScript:
1
2
3
4
5
6
Function.prototype.bind = function() {
  var __method = this, args = $A(arguments), object = args.shift();
  return function() {
    return __method.apply(object, args.concat($A(arguments)));
  }
}

[ Voor 4% gewijzigd door b19a op 07-04-2006 00:47 ]


  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
Hoe zouden jullie dit doen met settimeout achtige constructies?

Ik zie her en der stukjes code zonder quotes in de settimeout, maar daar krijg ik in mijn firefox netjes een error "useless unqouted settimeout value" terug, this. is na het aanroepen van de functie niet meer relevant in de object scope, omdat settimeout op het window object wordt uitgevoerd.

Iemand tips?

openkat.nl al gezien?


Verwijderd

Verwijderd schreef op zaterdag 18 februari 2006 @ 23:38:
In bepaalde gevallen moet je gewoon scopen.

var self = this;
window.setTimeout(function(){self.method()},35);

Als je dat niet zou doen, wordt method op je window object uitgevoerd.
kuch ;)

  • killercow
  • Registratie: Maart 2000
  • Laatst online: 20-02 08:34
sweet, helemaal niet gezien :P, jammer van de self=this reference, maar toch.

[ Voor 44% gewijzigd door killercow op 07-04-2006 11:03 ]

openkat.nl al gezien?


  • b19a
  • Registratie: September 2002
  • Niet online
killercow schreef op vrijdag 07 april 2006 @ 10:43:
Hoe zouden jullie dit doen met settimeout achtige constructies?

Ik zie her en der stukjes code zonder quotes in de settimeout, maar daar krijg ik in mijn firefox netjes een error "useless unqouted settimeout value" terug, this. is na het aanroepen van de functie niet meer relevant in de object scope, omdat settimeout op het window object wordt uitgevoerd.

Iemand tips?
JavaScript:
1
window.setTimeout(1000, this.timeHandler.bind(this));
Pagina: 1