web-dev-qa-db-fra.com

Passage de paramètres aux fichiers JavaScript

Souvent, je souhaite utiliser un fichier JavaScript nécessitant que certaines variables soient définies dans ma page Web.

Donc, le code ressemble à ceci:

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

Mais ce que je veux faire c'est:

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

J'ai essayé différentes méthodes et la meilleure consiste à analyser la chaîne de requête comme ceci:

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

Et ensuite chercher mes valeurs.

Je me demande s'il existe un autre moyen de faire cela sans construire une fonction pour analyser ma chaîne.

Connaissez-vous tous d'autres méthodes?

142
RaduM

Je recommanderais de ne pas utiliser de variables globales si possible. Utilisez un espace de noms et OOP pour transmettre vos arguments à un objet.

Ce code appartient à 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]);
        }
    };
}());

Et dans votre fichier html:

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

Vous pouvez passer des paramètres avec des attributs arbitraires. Cela fonctionne dans tous les navigateurs récents.

<script type="text/javascript" data-my_var_1="some_val_1" data-my_var_2="some_val_2" src="/js/somefile.js"></script>

Dans somefile.js, vous pouvez obtenir les valeurs des variables passées de cette façon:

........

var this_js_script = $('script[src*=somefile]'); // or better regexp to get the file name..

var my_var_1 = this_js_script.attr('data-my_var_1');   
if (typeof my_var_1 === "undefined" ) {
   var my_var_1 = 'some_default_value';
}
alert(my_var_1); // to view the variable value

var my_var_2 = this_js_script.attr('data-my_var_2');   
if (typeof my_var_2 === "undefined" ) {
   var my_var_2 = 'some_default_value';
}
alert(my_var_2); // to view the variable value

...etc...

65
Vlado

Une autre idée que j'ai eue à l'esprit était d'attribuer un "id" à l'élément et de transmettre les arguments en tant qu'attributs data *. La balise résultante ressemblerait à ceci:

<script id="helper" data-name="helper" src="helper.js"></script>

Le script peut ensuite utiliser l'identifiant pour se localiser par programme et analyser les arguments. Étant donné la balise précédente, le nom pourrait être récupéré comme ceci:

var name = document.getElementById("helper").getAttribute("data-name");

nous obtenons name = helper

34
NewBuddy

Découvrez cette URL. Cela fonctionne parfaitement pour l'exigence.

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

Merci beaucoup à l'auteur. Pour référence rapide, j'ai collé la logique principale ci-dessous:

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;
}
19
user378221

Voici une preuve de concept très précipitée.

Je suis sûr qu'il y a au moins deux endroits où des améliorations peuvent être apportées, et je suis également convaincu que cela ne survivrait pas longtemps dans la nature. Tous les commentaires pour le rendre plus présentable ou utilisable sont les bienvenus.

La clé consiste à définir un identifiant pour votre élément de script. Le seul problème est que cela signifie que vous ne pouvez appeler le script qu'une seule fois, car il recherche cet ID pour extraire la chaîne de requête. Cela pourrait être corrigé si, au lieu de cela, le script parcourait tous les éléments de la requête pour voir si l'un d'entre eux y était pointé et, le cas échéant, utilisait la dernière instance d'un tel élément de script. Quoi qu'il en soit, avec le code:

Le script étant appelé:

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 appelé via la page suivante:

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

<h1 id="docTitle"></h1>
<p id="docText"></p>
12
Anthony

Vous utilisez des variables globales :-D.

Comme ça:

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

Le code JavaScript dans 'file.js' peut accéder à obj1 et obj2 sans problème.

MODIFIER Je veux juste ajouter que si 'file.js' veut vérifier si obj1 et obj2 ont même été déclarés, vous pouvez utiliser la fonction suivante.

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

J'espère que cela t'aides.

11
NawaMan

pourrait être très simple

par exemple

<script src="js/myscript.js?id=123"></script>
<script>
    var queryString = $("script[src*='js/myscript.js']").attr('src').split('?')[1];
</script>

Vous pouvez ensuite convertir la chaîne de requête en json comme ci-dessous

var json = $.parseJSON('{"' 
            + queryString.replace(/&/g, '","').replace(/=/g, '":"') 
            + '"}');

et puis peut utiliser comme

console.log(json.id);
9
Tofeeq

Cela peut être facilement fait si vous utilisez un framework Javascript comme jQuery. Ainsi,

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

Vous pouvez maintenant utiliser ces paramètres en les divisant comme paramètres variables.

Le même processus peut être effectué sans aucune structure mais nécessitera plusieurs lignes de code.

6
GeekTantra

Belle question et réponses créatives, mais ma suggestion est de paramétrer vos méthodes, ce qui devrait résoudre tous vos problèmes sans astuces.

si vous avez la fonction:

function A()
{
    var val = external_value_from_query_string_or_global_param;
}

vous pouvez changer cela en:

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

Je pense que c'est l'approche la plus naturelle, vous n'avez pas besoin de créer de la documentation supplémentaire sur les "paramètres de fichier" et vous recevez les mêmes. Ceci est particulièrement utile si vous autorisez d'autres développeurs à utiliser votre fichier js.

1
dzida

Le fichier javascript peut être créé par l’un des langages de script et injecter vos variables dans le fichier à chaque requête. Vous devrez dire à votre serveur Web de ne pas distribuer les fichiers js de manière statique (utiliser mod_rewrite suffirait).

Sachez cependant que vous perdez toute mise en cache de ces fichiers js car ils sont constamment modifiés.

Au revoir.

1
aefxx

Ce n'est pas valide html (je ne pense pas) mais il semble fonctionner si vous créez un attribut personnalisé pour la balise script dans votre page Web:

<script id="myScript" myCustomAttribute="some value" ....>

Accédez ensuite à l'attribut personnalisé dans le javascript:

var myVar = document.getElementById( "myScript" ).getAttribute( "myCustomAttribute" );

Pas sûr que ce soit meilleur ou pire que d'analyser la chaîne source du script.

0
Cor

Non, vous ne pouvez pas vraiment faire cela en ajoutant des variables à la partie chaîne de requête de l'URL du fichier JS. Si son écriture de la partie de code pour analyser la chaîne qui vous dérange, peut-être une autre façon serait json encoder vos variables et les mettre dans quelque chose comme l'attribut rel de la balise? Je ne sais pas à quel point c'est valide en termes de validation HTML, si cela vous inquiète vraiment. Ensuite, il vous suffit de trouver l'attribut rel du script, puis json_decode that.

par exemple

<script type='text/javascript' src='file.js' rel='{"myvar":"somevalue","anothervar":"anothervalue"}'></script>
0
Dal Hundal