webForumDet fria alternativet

Använda eventhandlers för funktioner i objekt...

JavaScript

8 svar · 347 visningar · startad av nitro2k01

Medlem sedan aug. 20039 340 inlägg
Frågan#1

Betrakta följande kod:

<html>

<head>
<script>
function DivClass(inp, id){
	document.body.insertAdjacentHTML("beforeEnd", "<div name=\"xxx\" id=\"" + id + "\">Text: " + inp + " <br />Id: " + id + " </div>")
	this.el = document.getElementById(id);
// Mozilla
//	this.el.addEventListener("mousemove", this.mousemove)
// IE/Opera
	this.el.attachEvent("onmousemove", this.mousemove)
}

DivClass.prototype.mousemove=function(){
	this.test();
}

DivClass.prototype.test=function(){
	alert("Test ok!")
}

function loadpage(){
tdiv=new DivClass("Text", "ettid");
}
</script>
</head>
<body onload="loadpage();" >
</body>
</html>

Jag vill alltså att när musen förs över div'en ska funktionen tdiv.test() köras.
Problemet är att när man attachar en funktion på det här viset så skapas en kopia av funktionen. Det jag vill är att den ska refereras så att när eventet triggas, så är det den funktion test som ligger under objektet tdiv (Eller annan instans av DivClass) som körs, och inte en kopia av funktionen.

Går det?

Medlem sedan juli 2000534 inlägg
#2

Jag vet att det står om det här nånstans i Netscapes JavaScript Core Guide men jag kan inte hitta det just nu så det som står nedan är som jag kommer ihåg det i huvudet och kan därför vara fel...

Om du definerar din test()-metod självständigt och i konstruktorn för objektet refererar till den så borde det fungera som du vill. Alltså:

function DivClass(inp, id) {
  document.body.insertAdjacentHTML("beforeEnd", "<div name=\"xxx\" id=\"" + id + "\">Text: " + inp + " <br />Id: " + id + " </div>")
  this.el = document.getElementById(id);
// Mozilla
//  this.el.addEventListener("mousemove", this.mousemove)
// IE/Opera
  this.el.attachEvent("onmousemove", this.mousemove)
  [b]this.test = testfunction;[/b]
}

function testfunction() {
  alert('Test OK!');
}

Alternativt att du flyttar in hela funktionsdefinitionen i konstruktorn.

Medlem sedan aug. 20039 340 inlägg
#3

Som sagt, det funkar ändå inte, eftersom mousemove inte är refererad som event handler, utan att en kopia av funktionen mousemove är event handler. Därmed så motsvarar this inuti mousemove, när den fungerar som event handler, inte instansen av DivClass, utan något annat, kanske event-objektet eller div'en som funktionen kallades från. (Orkar inte kolla)
Ditt exempel gör i praktiken samma sak som mitt.

Det jag behöver är en funktion som attachar en event handler, men refererar den!

Medlem sedan aug. 2000374 inlägg
#4

Re: Använda eventhandlers för funktioner i objekt...

Två problem.

Första:

nitro2k01 skrev:

this.el.attachEvent("onmousemove", this.mousemove)

Ska du referera till en prototyp i konstruktorn så får du ändra this.mousemove till:

DivClass.prototype["mousemove"]

Andra:

nitro2k01 skrev:

DivClass.prototype.mousemove=function(){
	this.test();
}

this refererar inte till en DivClass instans utan till det DOM objektet som triggat händelsen, i detta fallet ett div objekt.

Det finns ett par olika lösningar på problemet, den enklaste är att skapa en referens till this i konstruktorn och använda denna i händelse hanteraren.

Medlem sedan aug. 20039 340 inlägg
#5

Re: Re: Använda eventhandlers för funktioner i objekt...

Hansen skrev:

Två problem.

Ska du referera till en prototyp i konstruktorn så får du ändra this.mousemove till:

DivClass.prototype["mousemove"]

Nej jag vill ju kunna knyta varje div till en (eller, bör nämnas, i vissa fall flera) instanser av objektet. Jag vill inte referera till funktionen i prototypen.

Hansen skrev:

Andra:

nitro2k01 skrev:

DivClass.prototype.mousemove=function(){
	this.test();
}

this refererar inte till en DivClass instans utan till det DOM objektet som triggat händelsen, i detta fallet ett div objekt.

Det vet jag ju... Det är lösningen jag är ute efter :)

Hansen skrev:

Det finns ett par olika lösningar på problemet, den enklaste är att skapa en referens till this i konstruktorn och använda denna i händelse hanteraren.

Hur då? Typ...

this.thisref = this;

...? Då kvarstår ju samma problem!

Medlem sedan aug. 2000374 inlägg
#6

Re: Re: Re: Använda eventhandlers för funktioner i objekt...

nitro2k01 skrev:

Hansen skrev:

Det finns ett par olika lösningar på problemet, den enklaste är att skapa en referens till this i konstruktorn och använda denna i händelse hanteraren.

Hur då? Typ...

this.thisref = this;

Nej, testa med en privat instans variabel.

Medlem sedan aug. 20039 340 inlägg
#7

Hmmm, ge gärna ett exempel... Var ska jag skapa variabeln för att den ska bli åtkomlig för den event handlern, men ändå specifik för ett objekt.

Medlem sedan aug. 2000374 inlägg
#8

nitro2k01 skrev:

[...]Var ska jag skapa variabeln för att den ska bli åtkomlig för den event handlern, men ändå specifik för ett objekt.

I konstruktorn.

var self = this;

Exempel:

    function Screamer(message) {
        var self = this;

        this.handler = function() {
            self.scream();
        }
        
        this.scream = function() {
            alert(message);
        }

        setTimeout( this.handler, 1000 );
    }
Medlem sedan aug. 20039 340 inlägg
#9

:o :o :o :o :o

:f :f :f :f :f

Tack så extremt mycket Hansen. Tack även morpher som försökte antyda detta tidgare. jag bara tog för givet att det inte skulle funka... :| (Och morpher, du glömde ju dock att flytta in handler-funktionen i konstruktorn.)

Hansen » Du svarade även på en annan fråga jag undrade över, nämligen hur man gör samma sak, men med setTimeout. Jag vet att jag har provat att skicka en funktion till setTimeout förut, men att det inte funkade. men det gjorde det visst nu!

Som sagt, tusen tack. Nu måste jag gå och försöka utveckla detta: Ett "fönster-i-webbläsaren"-system, som jag i princip hade övergett pga detta problem!

:f :f :f :f :f

299 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
167 ms — deklarationer (db)
0 ms — hämta statistik (cache)
130 ms — hämta tråd, inlägg och bilagor (db)
143 ms — ändringar (db)