web-dev-qa-db-fra.com

Comment puis-je inclure tous les fichiers JavaScript dans un répertoire via un fichier JavaScript?

J'ai un tas de fichiers JavaScript que je voudrais inclure dans la page, mais je ne veux pas avoir à continuer à écrire 

<script type="text/javascript" src="js/file.js"></script>

Alors, y a-t-il un moyen d'inclure tous les fichiers dans un répertoire (taille inconnue)? Puis-je faire quelque chose comme ...

$.getScript("js/*.js");

... pour obtenir tous les fichiers JavaScript dans le répertoire "js"? Comment puis-je faire cela en utilisant jQuery?

38
Hristo

En général, ce n’est probablement pas une bonne idée, car votre fichier HTML ne devrait charger que des fichiers JS qu’ils utilisent réellement. Quoi qu’il en soit, cela serait facile à faire avec n’importe quel langage de script côté serveur. Insérez simplement les balises de script avant de servir les pages au client.

Si vous souhaitez le faire sans utiliser de script côté serveur, vous pouvez déposer vos fichiers JS dans un répertoire permettant de répertorier le contenu du répertoire, puis utiliser XMLHttpRequest pour lire le contenu du répertoire, puis analyser les noms de fichiers et les charger. .

L'option n ° 3 consiste à créer un fichier JS "loader" qui utilise getScript () pour charger tous les autres fichiers. Mettez cela dans une balise de script dans tous vos fichiers HTML, puis il vous suffira de mettre à jour le fichier du chargeur chaque fois que vous téléchargerez un nouveau script. 

24
Mark Bessey

Pourquoi ne pas utiliser un script côté serveur pour générer les lignes de balises du script? Cruellement, quelque chose comme ça (PHP) -

$handle=opendir("scripts/");

while (($file = readdir($handle))!==false) {
echo '<script type="text/javascript" src="$file"></script>';
}

closedir($handle);
21
jellyfishtree

Étant donné que vous voulez une solution 100% côté client, vous pourriez probablement théoriquement faire ceci:

Via XmlHttpRequest, obtenez la page de liste de répertoires pour ce répertoire (la plupart des serveurs Web renvoient une liste de fichiers s'il n'y a pas de fichier index.html dans le répertoire). 

Analyser ce fichier avec javascript, en extrayant tous les fichiers .js. Cela dépendra bien sûr du format de la liste de répertoires sur votre serveur Web/hôte Web.

Ajoutez les balises de script de manière dynamique, avec quelque chose comme:

function loadScript (dir, file) {
 var scr = document.createElement("script");
 scr.src = dir + file;
 document.body.appendChild(scr);
 }
12
rob

Vous pouvez utiliser quelque chose comme Grunt Include Source . Il vous donne une syntaxe Nice qui pré-traite votre code HTML, puis inclut tout ce que vous voulez. Cela signifie également que si vous configurez correctement vos tâches de construction, vous pouvez avoir tous ces éléments en mode dev, mais pas en mode prod, ce qui est plutôt cool. 

Si vous n'utilisez pas Grunt pour votre projet, il existe probablement des outils similaires pour Gulp ou d'autres coureurs de tâches.

3
bwest87

Vous ne pouvez pas faire cela en JavaScript, car JS est exécuté dans le browser, pas sur le serveur. Par conséquent, il ne connaissait rien des répertoires ou des autres ressources du serveur.

La meilleure option consiste à utiliser un script côté serveur comme celui posté par jellyfishtree.

2
Alberto Martinez

Vous ne pouvez pas le faire en Javascript depuis le navigateur ... Si j'étais vous, j'utiliserais quelque chose comme browserify . Écrivez votre code en utilisant les modules commonjs, puis compilez le fichier javascript en un.

Dans votre html, chargez le fichier javascript que vous avez compilé.

1

@ jellyfishtree ce serait mieux si vous créez un fichier php contenant tous vos fichiers js du répertoire et n'incluez ce fichier php que via une balise script. Les performances sont meilleures car le navigateur doit faire moins de demandes au serveur. Regarde ça:

javascripts.php:

<?php
   //sets the content type to javascript 
   header('Content-type: text/javascript');

   // includes all js files of the directory
   foreach(glob("packages/*.js") as $file) {
      readfile($file);
   }
?>


index.php:

<script type="text/javascript" src="javascripts.php"></script>

C'est tout!
S'amuser! :)

1
Pascal

Cela peut être fait entièrement côté client, mais tous les noms de fichiers javascript doivent être spécifiés. Par exemple, en tant qu'éléments de tableau: 

function loadScripts(){
   var directory = 'script/';
   var extension = '.js';
   var files = ['model', 'view', 'controller'];  
   for (var file of files){ 
       var path = directory + file + extension; 
       var script = document.createElement("script");
       script.src = path;
       document.body.appendChild(script);
   } 
 }
1
yurin

Une autre option assez courte:

<script type="text/javascript">
$.ajax({
  url: "/js/partials",
  success: function(data){
     $(data).find('a:contains(.js)').each(function(){
        // will loop through 
        var partial= $(this).attr("href");
        $.getScript( "/js/partials/" + partial, function( data, textStatus, jqxhr ) {});
     });
  }
});
</script>
0
Alan

Je cherchais une réponse à cette question et avais mes propres problèmes. J'ai trouvé quelques solutions à divers endroits et les ai regroupées dans ma propre réponse préférée. 

function exploreFolder(folderURL,options){
/* options:                 type            explaination

    **REQUIRED** callback:  FUNCTION        function to be called on each file. passed the complete filepath
    then:                   FUNCTION        function to be called after loading all files in folder. passed the number of files loaded
    recursive:              BOOLEAN         specifies wether or not to travel deep into folders
    ignore:                 REGEX           file names matching this regular expression will not be operated on
    accept:                 REGEX           if this is present it overrides the `ignore` and only accepts files matching the regex
*/
$.ajax({
    url: folderURL,
    success: function(data){
        var filesLoaded = 0,
        fileName = '';

        $(data).find("td > a").each(function(){
            fileName = $(this).attr("href");

            if(fileName === '/')
                return;  //to account for the (go up a level) link

            if(/\/\//.test(folderURL + fileName))
                return; //if the url has two consecutive slashes '//'

            if(options.accept){
                if(!options.accept.test(fileName))
                    //if accept is present and the href fails, dont callback
                    return;
            }else if(options.ignore)
                if(options.ignore.test(fileName))
                    //if ignore is present and the href passes, dont callback
                    return;

            if(fileName.length > 1 && fileName.substr(fileName.length-1) === "/")
                if(options.recursive)
                    //only recurse if we are told to
                    exploreFolder(folderURL + fileName, options);
                else
                    return;

            filesLoaded++;
            options.callback(folderURL + fileName);
            //pass the full URL into the callback function
        });
        if(options.then && filesLoaded > 0) options.then(filesLoaded);
    }
});
}

Ensuite, vous pouvez l'appeler comme ceci:

var loadingConfig = {
    callback: function(file) { console.log("Loaded file: " + file); },
    then: function(numFiles) { console.log("Finished loading " + numFiles + " files"); },
    recursive: true,
    ignore: /^NOLOAD/,
};
exploreFolder('/someFolderURL/', loadingConfig);

Cet exemple appelle ce rappel sur chaque fichier/dossier du dossier spécifié sauf pour ceux commençant par NOLOAD. Si vous voulez réellement charger le fichier dans la page, vous pouvez utiliser cette autre fonction d'aide que j'ai développée.

function getFileExtension(fname){
    if(fname)
        return fname.substr((~-fname.lastIndexOf(".") >>> 0) + 2);
    console.warn("No file name provided");
}
var loadFile = (function(filename){
    var img = new Image();

    return function(){
        var fileref,
            filename = arguments[0],
            filetype = getFileExtension(filename).toLowerCase();

        switch (filetype) {
            case '':
                return;
            case 'js':
                fileref=document.createElement('script');
                fileref.setAttribute("type","text/javascript");
                fileref.setAttribute("src", filename);
                break;
            case "css":
                fileref=document.createElement("link");
                fileref.setAttribute("rel", "stylesheet");
                fileref.setAttribute("type", "text/css");
                fileref.setAttribute("href", filename);
                break;
            case "jpg":
            case "jpeg":
            case 'png':
            case 'gif':
                img.src = filename;
                break;
            default:
                console.warn("This file type is not supported: "+filetype);
                return;
        }
        if (typeof fileref !== undefined){
            $("head").append(fileref);
            console.log('Loaded file: ' + filename);
        }
    }
})();

Cette fonction accepte un fichier JS | CSS | (image commune) fichier et le charge. Il exécutera également les fichiers JS . L’appel complet à exécuter dans votre script pour charger toutes les images et * stylesheets et d’autres scripts pourrait ressembler à ceci:

loadingConfig = {
    callback: loadfile,
    then: function(numFiles) { console.log("Finished loading " + numFiles + " files"); },
    recursive: true,
    ignore: /^NOLOAD/,
};
exploreFolder('/someFolderURL/', loadingConfig);

Cela fonctionne à merveille!

0
Frozenfrank