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>
28 svar · 1 703 visningar · startad av Web-Tor
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...
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>
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.
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?
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.
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?
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.
<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.
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.
dectgap »
Det funkar fint som tusan! :)
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. ;)
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!
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]. :(
<div onclick="execute((function(obj){foo();bar(obj);})(this));">Kör foo och bar</div>
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?
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(){
}
}
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)"
<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"?