par , 17/03/2016 à 17h41 (1753 Affichages)
.
Solution applicable seulement si les dépendances entre fichiers JS sont connues
Bonjour à tous,
J'avais besoin de charger dynamiquement des fichiers JS et CSS contenus dans un répertoire envoyé en paramètre pour gérer l'appel à FancyBox. L'objectif était de récupérer tous les fichiers JS et CSS de l'arborescence téléchargée sur le site FancyBox
Racine
|___responsive
|___fancyBox (niveau 1)
|___sources (niveau 2)
|___fic1.js
|___helpers (niveau 3)
|__fic2.js
L'explication de l'arborescence arrive plus bas
Mon traitement consistait donc à balancer le chemin du répertoire à partir duquel les fichiers du répertoire envoyé en paramètres (ici Source) et ceux des ses sous-répertoires étaient récupérés pour ensuite être chargés dans le DOM. Un bon vieux traitement de masse bien générique ![:mrgreen:](https://www.developpez.net/forums/images/smilies/icon_mrgreen.gif)
Le code était correct mais au chargement du premier fichier JS j'avais l'erreur suivante:
Uncaught TypeError: Cannot read property 'helpers' of undefined (19:07:50:809 | error, javascript)
Ayant la tête dure, j'ai cherché pourquoi cette erreur et j'ai enfin connecté !!
Cela vient des dépendances entre fichiers JavaScript. Un concept de base...Bon bref...le ![:traine:](https://www.developpez.net/forums/images/smilies/bouletr.gif)
Il faut donc s'assurer de charger les fichiers appelés avant les fichiers appelants. Problème comment traiter simplement cette contrainte.
Ma solution repose sur
- RecursiveIteratorIterator(new RecursiveDirectoryIterator(Pathfolder),RecursiveIteratorIterator::SELF_FIRST); qui permet de descendre toute l'arborescence des répertoire sous le répertoire passé en paramètre (ici Pathfolder) et d'en récupérer les fichiers sous chaque répertoire
- Et l'attribution d'un niveau calculé par rapport au nombre de "/" dans le chemin de chaque fichier retourné par RecursiveIteratorIterator hors racine et répertoire passé en paramètre.Le niveau est attribué dans le fichier filesFolderList.php avec le code suivant : $filesList[] = array ("fic"=> $fullFile, "level"=>substr_count($fullFile,"/"));
Si je code dans le fichier PHP
$objectsFolder = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fullPathFolder), RecursiveIteratorIterator::SELF_FIRST);
alors (nous verrons plus tard à quoi correspond chemin)
- $objectsFolder[0] = racine/responsive/fancyBox/sources/helpers/js02.js"
- $objectsFolder[1] = racine/responsive/fancyBox/sources/js01.js
Donc dans notre exemple, tous les fichiers dans helpers appellent un ou plusieurs fichiers dans sources - js02.js appelle js01.js
Bon ça c'est la théorie, du blabla. Pour mieux comprendre, voici le code
Je charge en dur dans le fichiers html les fichiers suivants dans cette ordre car ownIndexDomReady.js appelle filesManager.js
1 2
| <script src="js/own/filesManager.js"></script>
<script src="js/own/ownIndexDomReady.js"></script> |
le code de filesManager.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| function ajaxOutput(optFolder)
{ var pathFolderJSon= {};
pathFolderJSon = optFolder;
var jqXHResponse = $.ajax
({ //async : true,
type: "POST",
url: "php/filesFolderList.php",
data: pathFolderJSon,
dataType: "json" //Le format JSon texte est toujours initialisé
});
return jqXHResponse;
}
function loadFile(pathFolder )
{ var jqXHR = ajaxOutput(pathFolder);
jqXHR.success(function (jqXHRData)
{ var filePath ="";
var scriptDOM ="";
for (i = 0; i < jqXHRData.length; i++)
{ filePath = jqXHRData[i]["fic"] ;
if (filePath.substr(-3) ==="css")
{ scriptDOM = "<link href='" +filePath + "' rel='stylesheet' type='text/css' media='screen'>";
$('head').append(scriptDOM);
}
else if (filePath.substr(-2) ==="js")
{ scriptDOM = "<script type='text/javascript' src='" +filePath + "'><\/script>";
//$('<script />', { type : 'text/javascript', src : filePath}).appendTo('head');
$('head').append(scriptDOM);
}
}
var ListView1Options = { inset: false };
$("#ListView1").listview(ListView1Options);
$("a[data-rel='PhotoGallery1']").attr('rel', 'PhotoGallery1');
$("a[rel^='PhotoGallery1']").fancybox({});
$("a[data-rel='PhotoGallery1']").fancybox(
{ helpers :
{ buttons: {},
thumbs: {}
}
}); // fancybox
});
}// loadFile |
le code de ownIndexDomReady.js
1 2 3 4 5 6
| $(document).ready(function() {
var optFolder = {};
optFolder.masterFolder = "responsive"; //car mon projet est sous racine/responsive
optFolder.path = "fancyBox-fullpack/source";//répertoire père de 1er niveau
loadFile(optFolder);
}); |
Le code du fichier PHP filesFolderList.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <?php
require "sortByKeyValue.php";
$masterFolder = urldecode($_POST['masterFolder']);// car doit être rajouté à la racine
$pathFolder = urldecode($_POST['path']);
$docRoot = $_SERVER['DOCUMENT_ROOT'];
$pathRoot = (empty($masterFolder)?$docRoot."/": $docRoot."/".$masterFolder."/");// Si le projet est directement sous la racine
$lenRoot =strlen($pathRoot );
$fullPathFolder=$pathRoot .$pathFolder;
if ($docRoot ==="D:/xampp/htdocs"){$fullPathFolder = json_decode(str_replace("/", "\\", json_encode($fullPathFolder)));} // En local reconnait backslash (\) alors que chez mon hebergeur ce sont les slash(/).Pourquoi ????
$objectsFolder = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fullPathFolder), RecursiveIteratorIterator::SELF_FIRST);
foreach ($objectsFolder as $file)
{ if (!$file->isDir())
{ if (substr($file,-2 ) ==='js' or substr($file,-3) ==='css')
{ $fullFile = substr($file,$lenRoot, strlen($file) - $lenRoot+1) ;
$fullFile = str_replace("\\", "/", $fullFile);// car pour le DOM c'est avec slash(/)
$filesList[] = array ("fic"=> $fullFile, "level"=>substr_count($fullFile,"/"));
}
}
}
$keyNameArray= "level";
$filesList1= sortArrayByKeyValue($filesList, $keyNameArray);
$returnData = json_encode($filesList1);
echo $returnData;
?> |
le code du fichier PHP sortByKeyValue.php pompé sans vergogne sur fonctionarray-multisort mais désolé de ne pouvoir citer l'auteur de cette procédure, pas sauvegardé son lien direct.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
<?php
/*
trie un tableau multi-dimensions par valeur de la clé reçue en paramètre par ordre décroissant du nombre de /, exactement ce qu'il me fallait
Encore merci à l'auteur dont j'ai pas sauvegardé le profil.
*/
function sortArrayByKeyValue($filesList,$keyNameArray)
{ $sortArray = [];
foreach($filesList as $item)
{ foreach($item as $key=>$value)
{ if(!isset($sortArray[$key]))
{ $sortArray[$key] = array();
}
$sortArray[$key][] = $value;
}
}
array_multisort($sortArray[$keyNameArray],SORT_ASC,$filesList);
return $filesList;
} |
Et voilà