Welcome to WebmasterWorld Guest from 54.221.9.209

Forum Moderators: open

Message Too Old, No Replies

inserting a variable into a function

     
4:26 pm on Dec 3, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 10, 2005
posts:387
votes: 0


I want to insert a variable into the settings I pass in a function. My code is:

function do_func() { pageFx("#ID", {setting: 'value', callback: do_func2_ + URL }); }

where 'pageFx' is the script call for a third-party animation script, and the {...} are my settings for that script. The problem is the callback -- I want to add part of the page URL to the function name so as not to conflict w/like-named functions on other pages. I set var URL earlier and want to add it here. But the javascript only reads 'do_func2_' as the name, omitting var URL. I tried adding quotes around "do_func2_" but that doesn't work either.

What's missing?
5:06 pm on Dec 3, 2012 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member fotiman is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Oct 17, 2005
posts: 4966
votes: 10


Is the callback value supposed to be a string, or a function reference? It's not exactly clear from the code you provided. Here's an example that you can play around with:

<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<script>
// externally defined function
function pageFx(selector, settings) {
alert(typeof(settings.callback) + ": " + settings.callback);
if (typeof(settings.callback) === "string") {
eval(settings.callback + "()");
}
else {
settings.callback();
}
}
var do_func2 = "do_func2_";
var URL = "example_com";
function do_func2_example_com() {
alert('in callback');
}
function do_func() {
pageFx(
"#ID",
{
setting: 'value',
//callback: do_func2 + URL
callback: do_func2_example_com
}
);
}
do_func();
</script>
</body>
</html>
5:16 pm on Dec 3, 2012 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member lucy24 is a WebmasterWorld Top Contributor of All Time Top Contributors Of The Month

joined:Apr 9, 2011
posts:12707
votes: 244


I tried adding quotes around "do_func2_" but that doesn't work either.

Did you try adding an intervening step? You said URL is already defined as a variable.

squiggle = "do_func2_" + URL;
callback: squiggle;

alert(typeof(settings.callback) + ": " + settings.callback)

Hee. Me too. "Oh, so that's what it thinks it's doing!" or possibly "Uhm, I'm sure the content of the string isn't supposed to be 'undefined'."
5:20 pm on Dec 3, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 10, 2005
posts:387
votes: 0


Yikes! Was hoping for a simple line or two! No - it's not a string. It runs perfectly if I hard-code the function name, like so:

function do_func() { pageFx("#ID", {setting: 'value', callback: do_func2_URLpage }); }

I don't really want to run it via alert(). Is there an easier way?

Thanks for your help.
5:30 pm on Dec 3, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 10, 2005
posts:387
votes: 0


I'm having a similar(?) problem elsewhere - I want to slice a string using a variable as one of the slice() parameters, but javascript doesn't read the variable. Here's my code:

var x = '/unwanted_directory_in_URL/';
var y = x.length;
URL = URL.slice(y);

My javascript knowledge is limited. The question in both cases is how to insert a variable where js is expecting a hard-coded value.
5:36 pm on Dec 3, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 10, 2005
posts:387
votes: 0


Hi Lucy - sorry, just saw your post. Tried it, but the script just thinks the function name is "squiggle"
5:39 pm on Dec 3, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 10, 2005
posts:387
votes: 0


Isn't there a way to break out of "text-mode" and into straight js parsing? In php, you use a period, like so:

"setting: " . $value . "callback: do_func2_" . $URL

I thought that's what the '+' is for in js, but it doesn't work here.
6:00 pm on Dec 3, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 10, 2005
posts:387
votes: 0


Update: I used a work-around for my second issue; still can't solve the first. Don't really want to have PHP spit out the whole JS code, with vars already inserted...
6:07 pm on Dec 3, 2012 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member fotiman is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Oct 17, 2005
posts: 4966
votes: 10



I don't really want to run it via alert(). Is there an easier way?

I wasn't suggesting that... it was just a way to help you debug what is going on.

It runs perfectly if I hard-code the function name, like so:

function do_func() { pageFx("#ID", {setting: 'value', callback: do_func2_URLpage }); }

Ok, so it looks like it's expecting a function reference then. If your function is named "do_func2_URLpage", as in:

function do_func2_URLpage() {
//...
}

And you want to dynamically generate this function reference as opposed to statically passing it in, then you could use eval to do it like this:

callback: eval("do_func2_" + URL)

eval will evaluate a string as a script expression, thus converting the strings "do_func2_" and whatever is defined in URL (in this case, "URLpage"), into the expression do_func2_URLpage, which is the reference to your function.

Hope that works.
8:23 pm on Dec 3, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 10, 2005
posts:387
votes: 0


Ahhh! That's it -- thanks, Fotiman; once again, "you da man". (Sorry for missing your intent with the alert func -- told you my js is bad.)

Now...there's still one lingering problem. This whole script is running as an eternal file from my main script. For some reason, a function called from the main script, and defined here in the external script, runs fine; but a function called here in the external script, and defined in the main script returns a "function undefined" error.

Is there something I need to do to make functions "global" so they're available to an external file?
2:50 am on Dec 4, 2012 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Nov 3, 2005
posts:1585
votes: 0


There is no need to eval() in this case

rather than
callback: eval("do_func2_" + URL)

try
callback: window["do_func2_" + URL]

Note that do_func2_XXX is short for window.do_func2_XXX and that a.b can always be written as a['b']
1:55 pm on Dec 4, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 10, 2005
posts:387
votes: 0


Thanks, that works too -- is there a reason it's preferable to eval()?

P.S. Still looking for a solution to getting external js files to read functions defined in <script> tags on my HTML page.
2:11 pm on Dec 4, 2012 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member fotiman is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Oct 17, 2005
posts: 4966
votes: 10


eval is an expensive operation. It's often said that eval is evil. :) daveVk's solution is a better alternative.

Regarding your second problem...
Can you post more information about the order the files are included in your markup?

<script src="file1.js"></script><!-- can't call methods in file2.js yet -->
<script src="file2.js"></script>
<!-- now you have access to both files -->
4:44 pm on Dec 4, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 10, 2005
posts:387
votes: 0


<!DOCTYPE...>
<html...>
<head>
...
<script type="text/javascript" src="external_file.js"></script>

<script type="text/javascript">
function func1(){..., callback: func2;}
function func3(){...}
</script>


[external_file.js]

function func2(){..., callback: func3;}


func1 & func2 run fine; func3 does not. I can put it in the external file if req'd, but just want to understand the scripting rules here. I thought the browser parses all code, including external files, then executes, so that sequence doesn't matter. Apparently, that's wrong.

Strangely(?): If I put the external file ref AFTER the script, func2 runs (even though it hasn't yet been defined when called in the main script). Plus, other functions in my external file don't run from calls in that same file (even though they run fine in the first setup). So the script never even gets around to returning to func3 on my HTML page (my external file has more to it than indicated above; it's more like func2 => cycle thru func2a a few times => then return to func3 on the main page).
7:37 pm on Dec 4, 2012 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member fotiman is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Oct 17, 2005
posts: 4966
votes: 10


The code, as you describe it, should work. I verified this with the following very simplistic base case:

<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<script src="external_file.js"></script>
<script>
function func1() {
func2();
}
function func3() {
alert('in func3');
}
func1();
</script>
</body>
</html>


// external
function func2() {
func3();
}


So perhaps something else is failing (and thus erroring out) before you think.
8:19 pm on Dec 4, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 10, 2005
posts:387
votes: 0


hmmm...you're right, now it's working; must have been something else in the earlier run.

One last question: is there a way to apply my variable (URL in my orig example) to the definition of the function, in addition to the call like you described? Like so:

function do_func2_ + URL () {...}
9:15 pm on Dec 4, 2012 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member fotiman is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Oct 17, 2005
posts: 4966
votes: 10


Yes, just like you reference it... via the window object:


var URL = "foo";
// define the function
window["do_func2_" + URL] = function() {
alert('in function');
}
// call the function
window["do_func2_" + URL]();
11:08 pm on Dec 4, 2012 (gmt 0)

Preferred Member

10+ Year Member

joined:Nov 10, 2005
posts:387
votes: 0


Great -- that's it. I actually thought of/tried that, but had the wrong syntax.

Many thanks Fotiman.