webForumDet fria alternativet

Skicka in funktion till funktion

JavaScriptur Javascript

28 svar · 1 703 visningar · startad av Web-Tor

Medlem sedan nov. 200013 890 inlägg
Frågan#1

Jag vill skicka in en funktion (func1) till en annan funktion (func2) och därifrån ska den första funktionen exekveras.

<script type="text/javascript">
function func2(obj){
	// alert(obj); « Här vill jag exekvera func1
}
</script>

<div onclick="func2('func1(\\'alert(123)\\');')">Save</div>

Jag vet att det är ett dumt exempel men...

Medlem sedan aug. 20039 342 inlägg
#2

Så där?

<script type="text/javascript">
function func1(disp){
	alert ("Detta skickades till func1: " + disp);
}

function func2(funcref, argument){
	funcref(argument);
}

func2(func1, "Test");
</script>
Medlem sedan juni 200032 969 inlägg
#3

Eval() ?

Medlem sedan feb. 20011 198 inlägg
#4

Detta borde funka.

<script type="text/javascript">
function func2(obj){
window.setTimeout(obj,0);
}
function func1(obj){
window.setTimeout(obj,0);
}
</script>

<div onclick="func2('func1(\'alert(123)\');')">Save</div>

/RED Värst vad folk var på hugget.

Medlem sedan nov. 200013 890 inlägg
#5

Ja, ni var verkligen på hugget. Härligt! :)

eval() hade ju varit smidigt men jag kan inte få den att exekvera min funktion?

Sedan är det så att ibland kan func2 innehålla flera funktioner. Det gör att jag helst inte vill ange namnet på funktionen func1 i själva scriptet. Jag skulle bara vilja func2 kör allt som kommer in som argument. Länken kan alltså se ut så här:

<div onclick="func2('func1(\\'alert(123)\\');func3(\\'alert(111)\\');')">Save</div>

Hänger ni med?

Medlem sedan aug. 20039 342 inlägg
#6

Du måste escapa!

<div onclick="eval('eval(\\'alert(123)\\');eval(\\'alert(111)\\');')">Save</div>

Jag tror tyvärr att du missuppfattade meningen med min funktion. Till min funktion ska du skicka en referens. Det exmplet du visade ska du ha eval till!

/r Tydligen tog forum-koden bort escape-tecknen, fixat.

Medlem sedan nov. 200013 890 inlägg
#7

Jo, jag har escapat men som du märkte så tar forumet bort det. ;)
Jag har redigerat mina inlägg så att escape-tecknen syns.

Jag missuppfattade kanske din kod. Kan du visa ett exempel där man klickat på en länk?

Medlem sedan sep. 20021 655 inlägg
#8

Du kan även skicka in anonyma funktioner:

<script type="text/javascript">
function execFunction() {
   var i = arguments.length;

   while(i-->0)
      arguments[ i ]();
}

// Två olika sätt att skriva anonyma funktioner
execFunction(new Function("alert('abc')"), function(){alert('test')});
</script>

execFunction förutsätter att de argument den får in är funktioner.

Medlem sedan nov. 200013 890 inlägg
#9

Hur får jag det där att fungera ihop med min länk?

<div onclick="???">Save</div>
Medlem sedan sep. 20021 655 inlägg
#10
<div onclick="execFunction(new Function('alert(\\'abc\\')'), function(){alert('test')});">

De två sätten är bara för att illustrera att du kan skriva på olika sätt. Det är ju lämpligt att vara konsekvent.

Medlem sedan maj 200010 687 inlägg
#11

dectgap skrev:

Du kan även skicka in anonyma funktioner:

<script type="text/javascript">
function execFunction() {
   var i = arguments.length;

   while(i-->0)
      arguments[ i ]();
}

// Två olika sätt att skriva anonyma funktioner
execFunction(new Function("alert('abc')"), function(){alert('test')});
</script>

execFunction förutsätter att de argument den får in är funktioner.

Vackert dectgap. Har undrat lite över hur man gör för att skapa funktioner med oändligt antal inparametrar. :)
Jag hade dock skivit så här:

function execFunction()
{
	for (var i = 0; i < arguments.length; i++)
		arguments[i]();
}

Smaksak, men lite mindre kod. Och så deklareras i inne i loopen.

Medlem sedan nov. 200013 890 inlägg
#12

dectgap »
Det funkar fint som tusan! :)

Medlem sedan nov. 200013 890 inlägg
#13

Jag måste dra upp den här tråden eftersom jag har hittat en bugg i det här scriptet.
Jag får problem när man skickar in ett object med en av funktionerna.

<script>
function execute(){
	var i = arguments.length;
	while(i-->0){
		arguments[ i ]()
	}
}

function foo(){
	alert("foo")
}

function bar(obj){
	alert("bar: "+obj)
}
</script>

<div onclick="execute(function(){foo();bar(this)});">Kör foo och bar</div>

bar-funktionen borde ju alerta "bar: [object]" men istället så blir det "bar: [object Object]"

Evigt tacksam om någon kunde berätta varför. ;)

Medlem sedan aug. 20039 342 inlägg
#14

Det beror på att this syftar på något annat när du kör funktionen, vad jag kan se syftar den på den anonyma funktionen i onclick-handlern. Explorer har tyvärr den dåliga smaken att ge alla objekt typen Object.
För att demonstrera detta så kan du pröva denna kod:

<div onclick="bar(this);">Kör foo och bar (2)</div>

I IE, så visar den också bara bar: [object Object], men i FF visar den det mer rättvisande: bar: [object HTMLDivElement]
Sen antar jag att IE kallar vissa object för enbart [object], vet ej varför!

Medlem sedan nov. 200013 890 inlägg
#15

nitro2k01 skrev:

För att demonstrera detta så kan du pröva denna kod:

<div onclick="bar(this);">Kör foo och bar (2)</div>

I IE, så visar den också bara bar: [object Object], men i FF visar den det mer rättvisande: bar: [object HTMLDivElement]
Sen antar jag att IE kallar vissa object för enbart [object], vet ej varför!

I min Explorer (6.0) så visar ovanstående kod "bar: [object]" vilket är precis vad jag vill. Det är bara när jag kör genom execute()-funktionen som [object] blir [object Object] istället och då funkar ingenting av min resterande kod. :(

Det går helt enkelt inte att komma åt några egenskaper i ett [object Object]. :(

Medlem sedan dec. 20025 483 inlägg
#16
<div onclick="execute((function(obj){foo();bar(obj);})(this));">Kör foo och bar</div>
Medlem sedan nov. 200013 890 inlägg
#17

Det börjar ta sig. :) Nu får jag i alla fall fram objektet till bar() funktionen men jag får ett fel i execute(). Det klagas på rad 5:

<script>
function execute(){
	var i = arguments.length;
	while(i-->0){
		arguments[i]()
	}
}

function foo(){
	alert("foo")

}

function bar(obj){
	alert("bar: "+obj)

}
</script>

<div onclick="execute((function(obj){foo();bar(obj);})(this));">Kör foo och bar (4)</div>

Sedan så är poängen med execute functionen att den ska kunna hindra andra funktioner från att köras. Om en knapp inte ska gå att tycka på så ska funktionerna som ligger inom execute() inte köras men med din kod så kört foo() och bar() först...

Hänger ni med?

Medlem sedan dec. 20025 483 inlägg
#18

Hm, jag missuppfattade dig lite. Den kod jag skickade med senast gör ju faktiskt inte alls det du vill. Jag tror det kan bli svårt att skicka med argument till en funktion i ett funktionsanrop, utan att denne exekverar. I koden ovan körs ju den anonyma funktionen "på plats" och skickar med returvärdet till execute(). Därav felet som uppstod.

Istället kanske man kan göra så här:

function execute(){
	var i = arguments.length;
	while (i-->0){
		if (arguments[i].constructor == Array){
			arguments[i][0](arguments[i].slice(1, arguments[i].length));
		} else {
			arguments[i]();
		}
	}
}

<div onclick="execute(foo,[bar,this])">Kör foo och bar</div>

Skulle en funktion behöva argument skickar du med en referens till funktionen, tillsammans med argumenten, i en array.

Det sista hängde jag inte med på ;) Är execute() kopplad till knappen? I sådana fall, varför inte sätta disabled på knappen? Anropas foo() och bar() från något annan ställe än execute()? Om inte, varför inte göra dem till lokala funktioner:

function f(){
    function g(){
    }
}
Medlem sedan nov. 200013 890 inlägg
#19

foo() och bar() anropas på en massa olika sätt och det är bara ibland som man går via execute() funktionen.

Sedan så är det inte alltid knappar som man trycker på utan ibland är det länkar eller div-taggar så jag kan inte köra med bara disabled.

I det här fallet så kört ju aldrig foo() och bar() men om man tar bort class="disabled" på div-taggen så körs dom.

<script>
function execute(){
	if(window.event.srcElement.className.indexOf("disabled")==-1){
		var i = arguments.length;
		while(i-->0){
			arguments[ i ]()
		}
	}
}

function foo(){
	alert("foo")

}

function bar(obj){
	alert("bar: "+obj)
}
</script>

<div class="disabled" onclick="execute(function(){foo();bar(this)});">Kör foo och bar</div>

Jag skulle ju helst vilja behålla formatet på det som står i fetstil eftersom det är så anropet ser ut på alla ställen där jag inte går via execute():
onclick="bar(this)"

Medlem sedan dec. 20025 483 inlägg
#20
<div onclick="execute((function(obj){return function(){foo(); bar(obj);}})(this))">execute()</div>

Du vill alltså förhindra att exempelvis bar() anropas utanför execute(), om elementet som exekverar funktionen har class="disabled"?

133 ms totalt · 3 externa anrop · v20260731065814-full.25f56b17
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
130 ms — hämta tråd, inlägg och bilagor (db)