file appeler - Comment inclure un fichier JavaScript dans un autre fichier JavaScript?



une fonction (25)

Y a-t-il quelque chose dans JavaScript similaire à @import dans CSS qui vous permet d'inclure un fichier JavaScript dans un autre fichier JavaScript?


Answers

En langage moderne, ce serait

function loadJs( url ){
  return new Promise( resolve => {
    const script = document.createElement( "script" );
    script.src = url;
    script.onload = resolve;
    document.head.appendChild( script );
  });
}

Les anciennes versions de JavaScript n’avaient pas d’importation, d’inclusion ou de nécessité, et de nombreuses approches différentes de ce problème ont été développées.

Mais depuis 2015 (ES6), JavaScript utilise le module ES6 standard pour importer des modules dans Node.js, également pris en charge par la plupart des navigateurs modernes .

Pour assurer la compatibilité avec les anciens navigateurs, des outils de build et / ou de transpilation peuvent être utilisés.

Modules ES6

Les modules ECMAScript (ES6) sont pris en charge dans Node.js depuis la version 8.5, avec l' --experimental-modules . Tous les fichiers impliqués doivent avoir l'extension .mjs .

// module.mjs
export function hello() {
  return "Hello";
}
// main.mjs
import { hello } from 'module'; // or './module'
let val = hello();  // val is "Hello";

Modules ECMAScript dans les navigateurs

Les navigateurs prennent en charge le chargement direct des modules ECMAScript (aucun outil comme Webpack requis) since Safari 10.1, Chrome 61, Firefox 60 et Edge 16. Consultez le support actuel sur caniuse .

<script type="module">
  import { hello } from './hello.mjs';
  hello('world');
</script>
// hello.mjs
export function hello(text) {
  const div = document.createElement('div');
  div.textContent = `Hello ${text}`;
  document.body.appendChild(div);
}

En savoir plus sur: since

Importations dynamiques dans les navigateurs

Les importations dynamiques permettent au script de charger d’autres scripts selon les besoins:

<script type="module">
  import('hello.mjs').then(module => {
      module.hello('world');
    });
</script>

Pour en savoir plus, https://developers.google.com/web/updates/2017/11/dynamic-import

Node.js nécessite

L'ancien style d'importation de modules, encore largement utilisé dans Node.js, est le système module.exports/require .

// mymodule.js
module.exports = {
   hello: function() {
      return "Hello";
   }
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"   

Il existe d'autres moyens pour JavaScript d'inclure du contenu JavaScript externe dans les navigateurs ne nécessitant pas de prétraitement.

AJAX Chargement

Vous pouvez charger un script supplémentaire avec un appel AJAX, puis utiliser eval pour l'exécuter. C'est le moyen le plus simple, mais il est limité à votre domaine en raison du modèle de sécurité JavaScript du sandbox. L'utilisation de eval ouvre également la porte aux bugs, aux hacks et aux problèmes de sécurité.

jQuery Chargement

La bibliothèque jQuery fournit une fonctionnalité de chargement sur une seule ligne :

$.getScript("my_lovely_script.js", function() {
   alert("Script loaded but not necessarily executed.");
});

Chargement de script dynamique

Vous pouvez ajouter une balise de script avec l'URL du script dans le code HTML. Pour éviter les frais généraux de jQuery, il s'agit d'une solution idéale.

Le script peut même résider sur un autre serveur. De plus, le navigateur évalue le code. La <script> peut être injectée dans la page Web <head> ou insérée juste avant la </body> fermeture </body> .

Voici un exemple de la façon dont cela pourrait fonctionner:

function dynamicallyLoadScript(url) {
    var script = document.createElement("script");  // create a script DOM node
    script.src = url;  // set its src to the provided URL

    document.head.appendChild(script);  // add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead)
}

Cette fonction ajoutera une nouvelle <script> à la fin de la section d'en-tête de la page, l'attribut src étant défini sur l'URL attribuée à la fonction en tant que premier paramètre.

Ces deux solutions sont décrites et illustrées dans JavaScript Madness: Dynamic Script Loading .

Détecter quand le script a été exécuté

Maintenant, il y a un gros problème que vous devez connaître. Cela implique que vous chargiez le code à distance . Les navigateurs Web modernes chargeront le fichier et continueront à exécuter votre script actuel car ils chargent tout de manière asynchrone pour améliorer les performances. (Cela s'applique à la méthode jQuery et à la méthode de chargement manuel dynamique des scripts.)

Cela signifie que si vous utilisez ces astuces directement, vous ne pourrez pas utiliser votre code nouvellement chargé à la ligne suivante après l'avoir demandé à être chargé , car il sera toujours en cours de chargement.

Par exemple: my_lovely_script.js contient MySuperObject :

var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);

var s = new MySuperObject();

Error : MySuperObject is undefined

Ensuite, vous rechargez la page en appuyant sur F5 . Et il fonctionne! Déroutant...

Alors que faire à ce sujet?

Eh bien, vous pouvez utiliser le hack suggéré par l'auteur dans le lien que je vous ai donné. En résumé, pour les personnes pressées, il utilise un événement pour exécuter une fonction de rappel lorsque le script est chargé. Ainsi, vous pouvez mettre tout le code en utilisant la bibliothèque distante dans la fonction de rappel. Par exemple:

function loadScript(url, callback)
{
    // Adding the script tag to the head as suggested before
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;

    // Then bind the event to the callback function.
    // There are several events for cross browser compatibility.
    script.onreadystatechange = callback;
    script.onload = callback;

    // Fire the loading
    head.appendChild(script);
}

Ensuite, vous écrivez le code que vous souhaitez utiliser APRÈS que le script soit chargé dans une fonction lambda :

var myPrettyCode = function() {
   // Here, do whatever you want
};

Ensuite, vous lancez tout ça:

loadScript("my_lovely_script.js", myPrettyCode);

Notez que le script peut s'exécuter après le chargement du DOM ou avant, selon le navigateur et si vous avez inclus la ligne script.async = false; . Il y a un bon article sur le chargement de Javascript en général qui en parle.

Fusion de code source / prétraitement

Comme indiqué au début de cette réponse, de nombreux développeurs utilisent des outils de compilation / transpilation tels que Parcel, Webpack ou Babel dans leurs projets, ce qui leur permet d'utiliser la syntaxe JavaScript à venir, d'assurer la compatibilité ascendante des navigateurs plus anciens, de combiner des fichiers, de minifier, etc. effectuer le fractionnement de code, etc.


Cela devrait faire:

xhr = new XMLHttpRequest();
xhr.open("GET", "/soap/ajax/11.0/connection.js", false);
xhr.send();
eval(xhr.responseText);

Une autre façon, qui à mon avis est beaucoup plus propre, consiste à faire une demande Ajax synchrone au lieu d'utiliser une <script> . C’est aussi la façon dont Node.js gère les inclus.

Voici un exemple d'utilisation de jQuery:

function require(script) {
    $.ajax({
        url: script,
        dataType: "script",
        async: false,           // <-- This is the key
        success: function () {
            // all good...
        },
        error: function () {
            throw new Error("Could not load script " + script);
        }
    });
}

Vous pouvez ensuite l'utiliser dans votre code comme vous utiliseriez habituellement un include:

require("/scripts/subscript.js");

Et être capable d'appeler une fonction du script requis dans la ligne suivante:

subscript.doSomethingCool(); 

Vous pouvez également assembler vos scripts en utilisant PHP :

Fichier main.js.php :

<?php
    header('Content-type:text/javascript; charset=utf-8');
    include_once("foo.js.php");
    include_once("bar.js.php");
?>

// Main JavaScript code goes here

J'ai écrit un module simple qui automatise le travail d'importation / inclusion des scripts de module en JavaScript. Pour une explication détaillée du code, reportez-vous à la publication de blog JavaScript require / import / include modules .

// ----- USAGE -----

require('ivar.util.string');
require('ivar.net.*');
require('ivar/util/array.js');
require('http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');

ready(function(){
    //Do something when required scripts are loaded
});

    //--------------------

var _rmod = _rmod || {}; //Require module namespace
_rmod.LOADED = false;
_rmod.on_ready_fn_stack = [];
_rmod.libpath = '';
_rmod.imported = {};
_rmod.loading = {
    scripts: {},
    length: 0
};

_rmod.findScriptPath = function(script_name) {
    var script_elems = document.getElementsByTagName('script');
    for (var i = 0; i < script_elems.length; i++) {
        if (script_elems[i].src.endsWith(script_name)) {
            var href = window.location.href;
            href = href.substring(0, href.lastIndexOf('/'));
            var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length);
            return url.substring(href.length+1, url.length);
        }
    }
    return '';
};

_rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark
                                                   //the root directory of your library, any library.


_rmod.injectScript = function(script_name, uri, callback, prepare) {

    if(!prepare)
        prepare(script_name, uri);

    var script_elem = document.createElement('script');
    script_elem.type = 'text/javascript';
    script_elem.title = script_name;
    script_elem.src = uri;
    script_elem.async = true;
    script_elem.defer = false;

    if(!callback)
        script_elem.onload = function() {
            callback(script_name, uri);
        };
    document.getElementsByTagName('head')[0].appendChild(script_elem);
};

_rmod.requirePrepare = function(script_name, uri) {
    _rmod.loading.scripts[script_name] = uri;
    _rmod.loading.length++;
};

_rmod.requireCallback = function(script_name, uri) {
    _rmod.loading.length--;
    delete _rmod.loading.scripts[script_name];
    _rmod.imported[script_name] = uri;

    if(_rmod.loading.length == 0)
        _rmod.onReady();
};

_rmod.onReady = function() {
    if (!_rmod.LOADED) {
        for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){
            _rmod.on_ready_fn_stack[i]();
        });
        _rmod.LOADED = true;
    }
};

_.rmod = namespaceToUri = function(script_name, url) {
    var np = script_name.split('.');
    if (np.getLast() === '*') {
        np.pop();
        np.push('_all');
    }

    if(!url)
        url = '';

    script_name = np.join('.');
    return  url + np.join('/')+'.js';
};

//You can rename based on your liking. I chose require, but it
//can be called include or anything else that is easy for you
//to remember or write, except "import", because it is reserved
//for future use.
var require = function(script_name) {
    var uri = '';
    if (script_name.indexOf('/') > -1) {
        uri = script_name;
        var lastSlash = uri.lastIndexOf('/');
        script_name = uri.substring(lastSlash+1, uri.length);
    } 
    else {
        uri = _rmod.namespaceToUri(script_name, ivar._private.libpath);
    }

    if (!_rmod.loading.scripts.hasOwnProperty(script_name)
     && !_rmod.imported.hasOwnProperty(script_name)) {
        _rmod.injectScript(script_name, uri,
            _rmod.requireCallback,
                _rmod.requirePrepare);
    }
};

var ready = function(fn) {
    _rmod.on_ready_fn_stack.push(fn);
};

Il est possible de générer dynamiquement une balise JavaScript et de l'ajouter à un document HTML à partir d'un autre code JavaScript. Cela chargera le fichier JavaScript ciblé.

function includeJs(jsFilePath) {
    var js = document.createElement("script");

    js.type = "text/javascript";
    js.src = jsFilePath;

    document.body.appendChild(js);
}

includeJs("/path/to/some/file.js");

Si quelqu'un recherche quelque chose de plus avancé, essayez RequireJS . Vous obtiendrez des avantages supplémentaires, tels que la gestion des dépendances, une meilleure simultanéité et d'éviter la duplication (c'est-à-dire, récupérer un script plusieurs fois).

Vous pouvez écrire vos fichiers JavaScript dans des "modules", puis les référencer en tant que dépendances dans d'autres scripts. Ou vous pouvez utiliser RequireJS en tant que solution simple "allez chercher ce script".

Exemple:

Définissez les dépendances en tant que modules:

un-dependency.js

define(['lib/dependency1', 'lib/dependency2'], function (d1, d2) {

     //Your actual script goes here.   
     //The dependent scripts will be fetched if necessary.

     return libraryObject;  //For example, jQuery object
});

implementation.js est votre fichier JavaScript "principal" qui dépend de some-dependency.js

require(['some-dependency'], function(dependency) {

    //Your script goes here
    //some-dependency.js is fetched.   
    //Then your script is executed
});

Extrait du fichier README de GitHub :

RequireJS charge des fichiers JavaScript simples ainsi que des modules plus définis. Il est optimisé pour une utilisation dans le navigateur, y compris dans un Web Worker, mais peut être utilisé dans d'autres environnements JavaScript, tels que Rhino et Node. Il implémente l'API de module asynchrone.

RequireJS utilise des balises de script simples pour charger des modules / fichiers, ce qui devrait permettre un débogage facile. Il peut être utilisé simplement pour charger des fichiers JavaScript existants, afin que vous puissiez l'ajouter à votre projet existant sans avoir à réécrire vos fichiers JavaScript.

...


Ma méthode habituelle est:

var require = function (src, cb) {
    cb = cb || function () {};

    var newScriptTag = document.createElement('script'),
        firstScriptTag = document.getElementsByTagName('script')[0];
    newScriptTag.src = src;
    newScriptTag.async = true;
    newScriptTag.onload = newScriptTag.onreadystatechange = function () {
        (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') && (cb());
    };
    firstScriptTag.parentNode.insertBefore(newScriptTag, firstScriptTag);
}

Cela fonctionne très bien et n'utilise pas de rechargement de page pour moi. J'ai essayé la méthode AJAX (une des autres réponses) mais cela ne semble pas fonctionner aussi bien pour moi.

Voici une explication du fonctionnement du code pour les curieux: il crée essentiellement une nouvelle balise de script (après la première) de l'URL. Il le configure en mode asynchrone afin de ne pas bloquer le reste du code mais d'appeler un rappel lorsque le paramètre readyState (l'état du contenu à charger) passe à 'chargé'.


La plupart des solutions présentées ici impliquent un chargement dynamique. Je cherchais à la place un compilateur qui rassemble tous les fichiers dépendants en un seul fichier de sortie. La même chose que les préprocesseurs Less / Sass traitent la règle @import CSS @import . N'ayant rien trouvé de tel, j'ai écrit un outil simple pour résoudre le problème.

Voici donc le compilateur, https://github.com/dsheiko/jsic , qui remplace $import("file-path") manière sécurisée $import("file-path") par le contenu du fichier demandé. Voici le plugin Grunt correspondant: https://github.com/dsheiko/grunt-jsic .

Sur la branche principale de jQuery, ils concaténent simplement les fichiers source atomiques en un seul fichier commençant par intro.js et se terminant par outtro.js . Cela ne me convient pas car cela n'offre aucune flexibilité pour la conception du code source. Découvrez comment cela fonctionne avec jsic:

src / main.js

var foo = $import("./Form/Input/Tel");

src / Form / Input / Tel.js

function() {
    return {
          prop: "",
          method: function(){}
    }
}

Maintenant nous pouvons exécuter le compilateur:

node jsic.js src/main.js build/mail.js

Et obtenir le fichier combiné

build / main.js

var foo = function() {
    return {
          prop: "",
          method: function(){}
    }
};

Ou plutôt que d'inclure au moment de l'exécution, utilisez un script à concaténer avant le téléchargement.

J'utilise des Sprockets (je ne sais pas s'il y en a d'autres). Vous construisez votre code JavaScript dans des fichiers séparés et incluez les commentaires traités par le moteur Sprockets en tant que includes. Pour le développement, vous pouvez inclure des fichiers de manière séquentielle, puis pour la production, pour les fusionner ...

Voir également:


Voici la version généralisée de la façon dont Facebook le fait pour son bouton omniprésente Like:

<script>
  var firstScript = document.getElementsByTagName('script')[0],
      js = document.createElement('script');
  js.src = 'https://cdnjs.cloudflare.com/ajax/libs/Snowstorm/20131208/snowstorm-min.js';
  js.onload = function () {
    // do stuff with your dynamically loaded script
    snowStorm.snowColor = '#99ccff';
  };
  firstScript.parentNode.insertBefore(js, firstScript);
</script>

Si cela fonctionne pour Facebook, cela fonctionnera pour vous.

La raison pour laquelle nous recherchons le premier élément de script au lieu de la head ou du body est que certains navigateurs n'en créent pas s'ils sont manquants, mais nous avons la garantie d'avoir un élément de script - celui-ci. Plus d’informations sur http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ .


J'ai créé une fonction qui vous permettra d'utiliser un verbiage similaire à C # / Java pour inclure un fichier JavaScript. Je l'ai testé un peu, même à l'intérieur d' un autre fichier JavaScript, et cela semble fonctionner. Cela nécessite jQuery mais pour un peu de "magie" à la fin.

J'ai mis ce code dans un fichier à la racine de mon répertoire de script (je l'ai nommé global.js, mais vous pouvez utiliser ce que vous voulez. Sauf erreur de ma part, jQuery devrait être le seul script requis sur une page donnée. Gardez cela à l'esprit. est en grande partie non testée au-delà de certaines utilisations de base, il peut donc y avoir ou non des problèmes avec la façon dont je l'ai fait; utilisez-le à vos risques et périls

/**
* @fileoverview This file stores global functions that are required by other libraries.
*/

if (typeof(jQuery) === 'undefined') {
    throw 'jQuery is required.';
}

/** Defines the base script directory that all .js files are assumed to be organized under. */
var BASE_DIR = 'js/';

/**
* Loads the specified file, outputting it to the <head> HTMLElement.
*
* This method mimics the use of using in C# or import in Java, allowing
* JavaScript files to "load" other JavaScript files that they depend on
* using a familiar syntax.
*
* This method assumes all scripts are under a directory at the root and will
* append the .js file extension automatically.
*
* @param {string} file A file path to load using C#/Java "dot" syntax.
*
* Example Usage:
* imports('core.utils.extensions');
* This will output: <script type="text/javascript" src="/js/core/utils/extensions.js"></script>
*/
function imports(file) {
    var fileName = file.substr(file.lastIndexOf('.') + 1, file.length);

    // Convert PascalCase name to underscore_separated_name
    var regex = new RegExp(/([A-Z])/g);
    if (regex.test(fileName)) {
        var separated = fileName.replace(regex, ",$1").replace(',', '');
        fileName = separated.replace(/[,]/g, '_');
    }

    // Remove the original JavaScript file name to replace with underscore version
    file = file.substr(0, file.lastIndexOf('.'));

    // Convert the dot syntax to directory syntax to actually load the file
    if (file.indexOf('.') > 0) {
        file = file.replace(/[.]/g, '/');
    }

    var src = BASE_DIR + file + '/' + fileName.toLowerCase() + '.js';
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = src;

    $('head').find('script:last').append(script);
}

Je viens d'écrire ce code JavaScript (en utilisant Prototype pour la manipulation DOM ):

var require = (function() {
    var _required = {};
    return (function(url, callback) {
        if (typeof url == 'object') {
            // We've (hopefully) got an array: time to chain!
            if (url.length > 1) {
                // Load the nth file as soon as everything up to the
                // n-1th one is done.
                require(url.slice(0, url.length - 1), function() {
                    require(url[url.length - 1], callback);
                });
            } else if (url.length == 1) {
                require(url[0], callback);
            }
            return;
        }
        if (typeof _required[url] == 'undefined') {
            // Haven't loaded this URL yet; gogogo!
            _required[url] = [];

            var script = new Element('script', {
                src: url,
                type: 'text/javascript'
            });
            script.observe('load', function() {
                console.log("script " + url + " loaded.");
                _required[url].each(function(cb) {
                    cb.call(); // TODO: does this execute in the right context?
                });
                _required[url] = true;
            });

            $$('head')[0].insert(script);
        } else if (typeof _required[url] == 'boolean') {
            // We already loaded the thing, so go ahead.
            if (callback) {
                callback.call();
            }
            return;
        }

        if (callback) {
            _required[url].push(callback);
        }
    });
})();

Usage:

<script src="prototype.js"></script>
<script src="require.js"></script>
<script>
    require(['foo.js','bar.js'], function () {
        /* Use foo.js and bar.js here */
    });
</script>

Gist: http://gist.github.com/284442 .


Il y a une bonne nouvelle pour vous. Très bientôt, vous pourrez charger du code JavaScript facilement. Cela deviendra un moyen standard d'importer des modules de code JavaScript et fera partie du code JavaScript même.

Vous devez simplement écrire import cond from 'cond.js'; charger une macro nommée cond partir d’un fichier cond.js

Ainsi, vous n'avez pas besoin de faire appel à un framework JavaScript ni à effectuer explicitement des appels Ajax .

Faire référence à:


Ce script ajoutera un fichier JavaScript en haut de toute autre <script>balise:

(function () {
    var li = document.createElement('script'); 
    li.type = 'text/javascript'; 
    li.src= "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"; 
    li.async=true; 
    var s = document.getElementsByTagName('script')[0]; 
    s.parentNode.insertBefore(li, s);
})();

Si vous utilisez des travailleurs Web et souhaitez inclure des scripts supplémentaires dans la portée de ce dernier, les autres réponses fournies sur l'ajout de scripts à la headbalise, etc. ne fonctionneront pas pour vous.

Heureusement, les Web Workers ont leur propre importScriptsfonction, qui est une fonction globale dans la portée de Web Worker, native du navigateur lui-même car elle fait partie de la spécification .

Alternativement, comme le souligne la deuxième réponse la plus votée à votre question , RequireJS peut également gérer l’inclusion de scripts dans un Web Worker (s’appelant probablement importScriptslui-même, mais avec quelques autres fonctionnalités utiles).


Voici une version synchrone sans jQuery :

function myRequire( url ) {
    var ajax = new XMLHttpRequest();
    ajax.open( 'GET', url, false ); // <-- the 'false' makes it synchronous
    ajax.onreadystatechange = function () {
        var script = ajax.response || ajax.responseText;
        if (ajax.readyState === 4) {
            switch( ajax.status) {
                case 200:
                    eval.apply( window, [script] );
                    console.log("script loaded: ", url);
                    break;
                default:
                    console.log("ERROR: script not loaded: ", url);
            }
        }
    };
    ajax.send(null);
}

Notez que pour que ce domaine fonctionne, le serveur doit définir l'en allow-origin tête allow-origin dans sa réponse.


La @importsyntaxe permettant de réaliser une importation JavaScript de type CSS est possible à l'aide d'un outil tel que Mixture via leur .mixtype de fichier spécial (voir here ). J'imagine que l'application utilise simplement l'une des méthodes susmentionnées en interne, bien que je ne sache pas.

De la documentation de Mixture sur les .mixfichiers:

Les fichiers de mixage sont simplement des fichiers .js ou .css avec .mix. dans le nom du fichier. Un fichier de mix étend simplement les fonctionnalités d'un fichier de style ou de script normal et vous permet d'importer et de combiner.

Voici un exemple de .mixfichier qui combine plusieurs .jsfichiers en un seul:

// scripts-global.mix.js
// Plugins - Global

@import "global-plugins/headroom.js";
@import "global-plugins/retina-1.1.0.js";
@import "global-plugins/isotope.js";
@import "global-plugins/jquery.fitvids.js";

Mixture génère ceci sous scripts-global.jsforme de version modifiée ( scripts-global.min.js).

Remarque: je ne suis en aucun cas affilié à Mixture, mis à part son utilisation en tant qu'outil de développement frontal. Je suis tombé sur cette question en voyant un .mixfichier JavaScript en action (dans l’un des circuits d’affichage Mixture) et en étant un peu confus («vous pouvez le faire?» Me suis-je dit). J'ai ensuite réalisé qu'il s'agissait d'un type de fichier spécifique à l'application (quelque peu décevant, accepté). Néanmoins, imaginé que la connaissance pourrait être utile pour les autres.

MISE À JOUR : Le mélange est maintenant gratuit (hors ligne).

UPDATE : Le mélange est maintenant interrompu. Les anciens mélanges sont toujours disponibles


Si votre intention de charger le fichier JavaScript utilise les fonctions du fichier importé / inclus , vous pouvez également définir un objet global et définir les fonctions en tant qu'objets. Par exemple:

global.js

A = {};

fichier1.js

A.func1 = function() {
  console.log("func1");
}

fichier2.js

A.func2 = function() {
  console.log("func2");
}

main.js

A.func1();
A.func2();

Vous devez juste faire attention lorsque vous incluez des scripts dans un fichier HTML. La commande doit être comme ci-dessous:

<head>
  <script type="text/javascript" src="global.js"></script>
  <script type="text/javascript" src="file1.js"></script>
  <script type="text/javascript" src="file2.js"></script>
  <script type="text/javascript" src="main.js"></script>
</head>

Mieux vaut utiliser la méthode jQuery . Pour retarder l'événement prêt, appelez d'abord $.holdReady(true). Exemple ( source ):

$.holdReady(true);
$.getScript("myplugin.js", function() {
    $.holdReady(false);
});

var js = document.createElement("script");

js.type = "text/javascript";
js.src = jsFilePath;

document.body.appendChild(js);

Il y a beaucoup de réponses possibles à cette question. Ma réponse est évidemment basée sur un certain nombre d'entre elles. C'est ce que j'ai fini avec après avoir lu toutes les réponses.

Le problème avec $.getScripttoute autre solution nécessitant un rappel lorsque le chargement est terminé est que, si plusieurs fichiers l'utilisent et dépendent les uns des autres, vous ne pouvez plus savoir quand tous les scripts ont été chargés (une fois qu'ils sont imbriqués). dans plusieurs fichiers).

Exemple:

fichier3.js

var f3obj = "file3";

// Define other stuff

fichier2.js:

var f2obj = "file2";
$.getScript("file3.js", function(){

    alert(f3obj);

    // Use anything defined in file3.
});

fichier1.js:

$.getScript("file2.js", function(){
    alert(f3obj); //This will probably fail because file3 is only guaranteed to have loaded inside the callback in file2.
    alert(f2obj);

    // Use anything defined in the loaded script...
});

Vous avez raison de dire que vous pouvez spécifier qu'Ajax doit s'exécuter de manière synchrone ou utiliser XMLHttpRequest , mais la tendance actuelle semble être de désapprouver les demandes synchrones. Vous risquez donc de ne pas obtenir une prise en charge complète du navigateur, ni à l'avenir.

Vous pouvez essayer d'utiliser $.whenpour vérifier un tableau d'objets différés, mais maintenant vous le faites dans chaque fichier et fichier2 sera considéré comme chargé dès que le $.whenn'est pas exécuté lorsque le rappel est exécuté, de sorte que fichier1 continue l'exécution avant le chargement de fichier3. . Cela a toujours le même problème.

J'ai décidé de faire marche arrière au lieu d'avancer. Je vous remercie document.writeln. Je sais que c'est tabou, mais tant qu'il est utilisé correctement, cela fonctionne bien. Vous vous retrouvez avec un code qui peut être facilement mis au point, affiché correctement dans le DOM et peut garantir l'ordre de chargement correct des dépendances.

Vous pouvez bien sûr utiliser $ ("body"). Append (), mais alors vous ne pourrez plus déboguer correctement.

REMARQUE: vous devez utiliser ceci uniquement pendant le chargement de la page, sinon vous obtenez un écran vide. En d'autres termes, placez toujours ceci avant / en dehors de document.ready . Je n'ai pas testé l'utilisation de cette option après le chargement de la page dans un événement click ou quelque chose du genre, mais je suis certain que cela va échouer.

J'ai aimé l'idée d'étendre jQuery, mais vous n'avez évidemment pas besoin de le faire.

Avant d'appeler document.writeln, il vérifie que le script n'a pas déjà été chargé en évaluant tous les éléments du script.

Je suppose qu'un script n'est pas complètement exécuté tant que son document.readyévénement n'a pas été exécuté. (Je sais que l'utilisation document.readyn'est pas obligatoire, mais de nombreuses personnes l'utilisent, ce qui constitue une sauvegarde.)

Lorsque les fichiers supplémentaires sont chargés, les document.readyrappels seront exécutés dans le mauvais ordre. Pour résoudre ce problème lorsqu'un script est réellement chargé, le script qui l'a importé est réimporté lui-même et son exécution est arrêtée. Cela provoque maintenant le document.readyrappel du fichier d'origine, après n'importe quel script importé.

Au lieu de cette approche, vous pouvez essayer de modifier jQuery readyList, mais cela semble être une solution pire.

Solution:

$.extend(true,
{
    import_js : function(scriptpath, reAddLast)
    {
        if (typeof reAddLast === "undefined" || reAddLast === null)
        {
            reAddLast = true; // Default this value to true. It is not used by the end user, only to facilitate recursion correctly.
        }

        var found = false;
        if (reAddLast == true) // If we are re-adding the originating script we do not care if it has already been added.
        {
            found = $('script').filter(function () {
                return ($(this).attr('src') == scriptpath);
            }).length != 0; // jQuery to check if the script already exists. (replace it with straight JavaScript if you don't like jQuery.
        }

        if (found == false) {

            var callingScriptPath = $('script').last().attr("src"); // Get the script that is currently loading. Again this creates a limitation where this should not be used in a button, and only before document.ready.

            document.writeln("<script type='text/javascript' src='" + scriptpath + "'></script>"); // Add the script to the document using writeln

            if (reAddLast)
            {
                $.import_js(callingScriptPath, false); // Call itself with the originating script to fix the order.
                throw 'Readding script to correct order: ' + scriptpath + ' < ' + callingScriptPath; // This halts execution of the originating script since it is getting reloaded. If you put a try / catch around the call to $.import_js you results will vary.
            }
            return true;
        }
        return false;
    }
});

Usage:

File3:

var f3obj = "file3";

// Define other stuff
$(function(){
    f3obj = "file3docready";
});

Fichier2:

$.import_js('js/file3.js');
var f2obj = "file2";
$(function(){
    f2obj = "file2docready";
});

Fichier1:

$.import_js('js/file2.js');

// Use objects from file2 or file3
alert(f3obj); // "file3"
alert(f2obj); // "file2"

$(function(){
    // Use objects from file2 or file3 some more.
    alert(f3obj); //"file3docready"
    alert(f2obj); //"file2docready"
});

L' import relevé est dans ECMAScript 6.

Syntaxe

import name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import name , { member [ , [...] ] } from "module-name";
import "module-name" as name;

On ne redirige pas simplement en utilisant jQuery

jQuery n'est pas nécessaire et window.location.replace(...) simule au mieux une redirection HTTP.

window.location.replace(...) est préférable à window.location.href , car replace() ne conserve pas la page d'origine dans l'historique de session, ce qui signifie que l'utilisateur ne restera pas coincé dans un arrière sans fin bouton fiasco.

Si vous souhaitez simuler quelqu'un qui clique sur un lien, utilisez location.href

Si vous souhaitez simuler une redirection HTTP, utilisez location.replace

Par exemple:

// similar behavior as an HTTP redirect
window.location.replace("http://.com");

// similar behavior as clicking on a link
window.location.href = "http://.com";




javascript file import include