views:

572

answers:

9

Often I will have a JavaScript file that I want to use which requires certain variables be defined in my web page.

So the code is something like this:

<script type="text/javascript" src="file.js"></script>
<script type="text/javascript">
   var obj1 = "somevalue";
</script>

But what I want to do is:

<script type="text/javascript" 
     src="file.js?obj1=somevalue&obj2=someothervalue"></script>

I tried different methods and the best one yet is to parse the query string like this:

var scriptSrc = document.getElementById("myscript").src.toLowerCase();

And then search for my values.

I wonder if there is another way to do this without building a function to parse my string.

Do you all know other methods?

+2  A: 

You use Global variables :-D.

Like this:

<script type="text/javascript">
   var obj1 = "somevalue";
   var obj2 = "someothervalue";
</script>
<script type="text/javascript" src="file.js"></script">

The JavaScript code in 'file.js' can access to obj1 and obj2 without problem.

EDIT Just want to add that if 'file.js' wants to check if obj1 and obj2 have even been declared you can use the following function.

function IsDefined($Name) {
    return (window[$Name] != undefined);
}

Hope this helps.

NawaMan
+2  A: 

This can be easily done if you are using some Javascript framework like jQuery. Like so,

var x = $('script:first').attr('src'); //Fetch the source in the first script tag
var params = x.split('?')[1]; //Get the params

Now you can use these params by splitting as your variable parameters.

The same process can be done without any framework but will take some more lines of code.

GeekTantra
There's also a jQuery plugin called parseQuery that makes this even easier: http://plugins.jquery.com/project/parseQuery
Jimmy Cuadra
A: 

Well, you could have the javascript file being built by any of the scripting languages, injecting your variables into the file on every request. You would have to tell your webserver to not dish out js-files statically (using mod_rewrite would suffice).

Be aware though that you lose any caching of these js-files as they are altered constantly.

Bye.

aefxx
A: 

No, you cant really do this by adding variables to the querystring portion of the JS file URL. If its writing the portion of code to parse the string that bothers you, perhaps another way would be to json encode your variables and put them in something like the rel attribute of the tag? I don't know how valid this is in terms of HTML validation, if thats something you're very worried about. Then you just need to find the rel attribute of the script and then json_decode that.

eg

<script type='text/javascript' src='file.js' rel='{"myvar":"somevalue","anothervar":"anothervalue"}'></script>
Mailslut
You can do it with the fake querystring. It's just not a good idea. But neither is this. The rel attribute is meant to specify a type of link relationship, not cram random data into a script tag.
Matthew Flaschen
^^ agreed. I can't see any problems with just leaving it as is, and using the <script>var obj1="somevalue"</script> approach, its the best way, and I believe - the right way.
Mailslut
+1  A: 

I'd recommend not using global variables if possible. Use a namespace and OOP to pass your arguments through to an object.

This code belongs in file.js:

var MYLIBRARY = MYLIBRARY || (function(){
    var _args = {}; // private

    return {
        init : function(Args) {
            _args = Args;
            // some other initialising
        },
        helloWorld : function() {
            alert('Hello World! -' + _args[0]);
        }
    };
}());

And in your html file:

<script type="text/javascript" src="file.js"></script>
<script type="text/javascript">
   MYLIBRARY.init(["somevalue", 1, "controlId"]);
   MYLIBRARY.helloWorld();
</script>
Naeem Sarfraz
A: 

I don't know whether you can access your script's location from an imported script, but you can generate the variables on the server and insert them into the script.

generate_js.php:

header('Content-type: text/javascript');

$filename = $_GET['file'];
unset($_GET['file']);

foreach ($_GET as $key => $val) {
  echo "var $key = '$val';\n";
}

readfile($filename);

script.js:

alert(obj1);

page.htm:

<script type="text/javascript" src="generate_js.php?file=script.js&obj1=somevalue&obj2=someothervalue"></script>

This will dynamically insert your query string parameters into the script, so the output should be an alert with "somevalue".

Max Shawabkeh
+1  A: 

Here is a very rushed proof of concept.

I'm sure there are at least 2 places where there can be improvements, and I'm also sure that this would not survive long in the wild. Any feedback to make it more presentable or usable is welcome.

The key is setting an id for your script element. The only catch is that this means you can only call the script once since it looks for that ID to pull the query string. This could be fixed if, instead, the script loops through all query elements to see if any of them point to it, and if so, uses the last instance of such an script element. Anyway, on with the code:

Script being called:

window.onload = function() {
//Notice that both possible parameters are pre-defined.
//Which is probably not required if using proper object notation
//in query string, or if variable-variables are possible in js.
var header;
var text;

//script gets the src attribute based on ID of page's script element:
var requestURL = document.getElementById("myScript").getAttribute("src");

//next use substring() to get querystring part of src
var queryString = requestURL.substring(requestURL.indexOf("?") + 1, requestURL.length);

//Next split the querystring into array
var params = queryString.split("&");

//Next loop through params
for(var i = 0; i < params.length; i++){
 var name  = params[i].substring(0,params[i].indexOf("="));
 var value = params[i].substring(params[i].indexOf("=") + 1, params[i].length);

    //Test if value is a number. If not, wrap value with quotes:
    if(isNaN(parseInt(value))) {
  params[i] = params[i].replace(value, "'" + value + "'");
 }

    // Finally, use eval to set values of pre-defined variables:
 eval(params[i]);
}

//Output to test that it worked:
document.getElementById("docTitle").innerHTML = header;
document.getElementById("docText").innerHTML = text;
};

Script called via following page:

<script id="myScript" type="text/javascript" 
        src="test.js?header=Test Page&text=This Works"></script>

<h1 id="docTitle"></h1>
<p id="docText"></p>
Anthony
A: 

check below URL it is working perfectly for the requirement.

http://feather.elektrum.org/book/src.html

Thanks a lot to the author. For quick reference I pasted the main logic below

var scripts = document.getElementsByTagName('script'); var myScript = scripts[ scripts.length - 1 ];

var queryString = myScript.src.replace(/^[^\?]+\??/,'');

var params = parseQuery( queryString );

function parseQuery ( query ) { var Params = new Object (); if ( ! query ) return Params; // return empty object var Pairs = query.split(/[;&]/); for ( var i = 0; i < Pairs.length; i++ ) { var KeyVal = Pairs[i].split('='); if ( ! KeyVal || KeyVal.length != 2 ) continue; var key = unescape( KeyVal[0] ); var val = unescape( KeyVal[1] ); val = val.replace(/+/g, ' '); Params[key] = val; } return Params; }

+1  A: 

Nice question and creative answers but my suggetion is to make your methods paramterized and that should solve all your problems without any tricks.

if you have function:

function A()
{
    var val = external_value_from_query_string_or_global_param;
}

you can change this to:

function B(function_param)
{
    var val = function_param;
}

I think this is most natural approach, you don't need to crate extra documentation about 'file parameters' and you receive the same. This specially useful if you allow other developers to use your js file.

Lukasz Dziedzia