Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: JS: AddEventListener ongelma objektissa

Synomi [30.03.2012 10:13:20]

#

Tuossa tuli pieni ongelma vastaan kun JS objekteja pyöritteli. Koittanut saada kaiken tarpeellisen toiminnallisuuden suoraan objektiin, siten että voitaisiin luoda uusi objekti per Canvas samalla toiminnallisuudella tässä tapauksessa. Muuten onnistunutki, mutta tuli nyt ongelma kun EventListenereitä alkoi lisäämään.

Eli joudun lisäämään pääobjektissa EventListenerin sen alielementtiin ecanvakseen. Joten tästä EventListenerissä kutsutusta functiosta onMouseMovesta haluaisin päässä käsiksi suoraan tähän pääobjectiin jossa ecanvas on. Koodi on seuraavanlainen:

function Energia_object(canvasElement)
{
        //canvas init
        this.ecanvas = canvasElement;
        try
        {
            this.econtext = this.ecanvas.getContext('2d');
        }
        catch(ex)
        {
            alert("Virhe: " + ex);
            return false;
        }


        this.debug = function(text)
        {
            $('#debug').prepend(text + "<br />");
        }

        this.onMouseMove = function(e)
        {
            var x=e.clientX-this.offsetLeft+window.pageXOffset;
            var y=e.clientY-this.offsetTop+window.pageYOffset;

            this.debug("MouseMove: " + x + ", " + y);
        }

        this.onMouseClick = function(e)
        {
            var x=e.clientX-this.offsetLeft+window.pageXOffset;
            var y=e.clientY-this.offsetTop+window.pageYOffset;

            this.debug("MouseClick: " + x + ", " + y);

        }

        this.debug("init");


        //event listeners

        this.ecanvas.addEventListener("click",this.onMouseClick, false);
        this.ecanvas.addEventListener("mousemove",this.onMouseMove, false);

}

Eli haluaisin käyttää mm. tuota this.debug functiota this.onMouseMove function sisällä, mutta ei onnistu, koska tuo this.onMouseMove menee tuohon this.ecanvas elementtiin. Voikohan tuossa AddEventListenerin mukana laittaa tuon pääobjektin tms.

Lisäys:

Tommosella purkka ratkasulla tuo jotenki toimis jos laittais että pääobjectin nimi on sama ko canvaselementin id:

this.onMouseClick = function(e)
        {
            var x=e.clientX-this.offsetLeft+window.pageXOffset;
            var y=e.clientY-this.offsetTop+window.pageYOffset;

            $.globalEval(this.id + ".debug('purkkaclick')");
        }

Mutta tommosen käyttöä välttäis kyllä aika pitkälle.

jlaire [30.03.2012 11:09:22]

#

JavaScriptin this toimii vähän yllättävällä tavalla. Se, miten funktiota/metodia kutsutaan, vaikuttaa this:n arvoon sen sisällä.

function Foo1() {
    this.x = 5;
    this.get_x = function() {
        return this.x;
    };
}

var foo = new Foo1();
alert(foo.x);       // 5
alert(foo.get_x()); // 5
var get_x = foo.get_x;
alert(get_x());     // undefined

var x = "kissanpentu";
alert(get_x());     // "kissanpentu"

Kun kutsu on muotoa foo.get_x(), metodin sisällä this:n arvo on foo. Mutta kun funktio on erotettu objektista ja sitä kutsutaan yksinään, get_x(), sen sisällä this viittaakin globaaliin objektiin.

Yksi ratkaisu on tällainen:

function Foo2() {
    var self = this;
    this.x = 5;
    this.get_x = function() {
        return self.x;
    };
}

var foo = new Foo2();
var get_x = foo.get_x;
alert(get_x()); // 5

Eli tallennetaan this:n arvo paikalliseen muuttujaan konstruktorin alussa (nimi voi olla vaikka self) ja käytetään aina sitä this:n sijaan metodien sisällä.

Pidän parempana tapana this:n käyttöä ja kutsujen korjaamista niin, että se asettuu oikein, mutta en nyt jaksa kirjoittaa enempää. :)

Synomi [30.03.2012 11:27:14]

#

Jees tuohan oliki kätevä ja helppo tapa saada tuo toimimaan. Kiitti avusta.

tsuriga [30.03.2012 15:11:25]

#

Selfin tilalla näkee usein käytettävän nimitystä that, sillä self saattaa joissakin moottoreissa olla varattu sana, mm. joissakin Operan versioissa tähän muistaakseni törmättiin taannoin userscriptiä tehdessä. Toinen vaihtoehto on tosiaan tehdä bindaukset niin, että this toimii oikein, tähän esimerkkiä John Resigin kirjoituksesta ECMAScript 5 Strict Mode, JSON, and More.

jlaire [30.03.2012 15:43:50]

#

Aijaa. :o

Entisessä työpaikassa tuon nimi oli aina self eikä mihinkään siihen liittyviin ongelmiin törmätty. Muissakin koodeissa olen törmännyt samaan nimeen. Löysin nyt Googlella joitain valituksia siitä että globaaliin self-muuttujaan (eli window.self:iin) ei voisi asettaa Operassa, mutta eihän kukaan tuollaisia globaaleja tee. ;)

Minusta that on aika epäintuitiivinen nimi, mutta sitäkin kyllä näkee käytettävän ja kaikkeenhan tottuu.

tsuriga [30.03.2012 16:02:15]

#

Ei toki ;). Miusta molemmat that ja self on vähän kehnoja nimiä eri syistä. Heitetään soppaan vielä ehkä omasta mielestä selkein kun en äsken sitä muistanut, eli _this, sitäkin näkyy käytettävän.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta