pasar otro otra llamar incluir importar funcion desde con cargar archivo javascript file import include

otra - ¿Cómo incluyo un archivo JavaScript en otro archivo JavaScript?



llamar funcion javascript desde otra funcion javascript (30)

¿Hay algo en JavaScript similar a @import en CSS que le permita incluir un archivo JavaScript dentro de otro archivo JavaScript?


Acabo de escribir este código JavaScript (utilizando Prototype para la manipulación de 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); } }); })();

Uso:

<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 .


Aquí está la versión generalizada de cómo Facebook lo hace para su omnipresente botón Me gusta:

<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 funciona para Facebook, funcionará para ti.

La razón por la que buscamos el primer elemento de script lugar de la head o el body es porque algunos navegadores no crean uno si faltan, pero estamos seguros de que tenemos un elemento de script , este. Lea más en http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/ .


Aquí hay una versión sincrónica sin 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); }

Tenga en cuenta que para obtener este dominio cruzado de trabajo, el servidor deberá establecer el encabezado de allow-origin permitido en su respuesta.


En caso de que esté utilizando Trabajadores Web y desee incluir secuencias de comandos adicionales en el ámbito del trabajador, las otras respuestas proporcionadas sobre la adición de secuencias de comandos a la etiqueta de head , etc. no funcionarán para usted.

Afortunadamente, los Trabajadores Web tienen su propia función importScripts , que es una función global en el ámbito del Trabajador Web, nativa del navegador en sí, ya que forma parte de la especificación .

Alternativamente, como la segunda respuesta más votada a sus preguntas resaltadas , RequireJS también puede manejar la inclusión de scripts dentro de un Trabajador Web (es probable que llame a importScripts sí, pero con algunas otras características útiles).


En realidad, existe una forma de cargar un archivo JavaScript no de forma asíncrona, por lo que podría usar las funciones incluidas en su archivo recién cargado inmediatamente después de cargarlo, y creo que funciona en todos los navegadores.

jQuery.append() usar jQuery.append() en el elemento <head> de su página, es decir:

$("head").append(''<script type="text/javascript" src="'' + script + ''"></script>'');

Sin embargo, este método también tiene un problema: si ocurre un error en el archivo JavaScript importado, Firebug (y también la Consola de errores de Firefox y las Herramientas para desarrolladores de Chrome también) informará de su ubicación de forma incorrecta, lo cual es un gran problema si utiliza Firebug para realizar un seguimiento Los errores de JavaScript bajan mucho (lo hago). Firebug simplemente no conoce el archivo recién cargado por alguna razón, por lo que si ocurre un error en ese archivo, informa que ocurrió en su archivo HTML principal y tendrá problemas para descubrir la verdadera razón del error.

Pero si eso no es un problema para ti, entonces este método debería funcionar.

De hecho, he escrito un complemento de jQuery llamado $ .import_js () que usa este método:

(function($) { /* * $.import_js() helper (for JavaScript importing within JavaScript code). */ var import_js_imported = []; $.extend(true, { import_js : function(script) { var found = false; for (var i = 0; i < import_js_imported.length; i++) if (import_js_imported[i] == script) { found = true; break; } if (found == false) { $("head").append(''<script type="text/javascript" src="'' + script + ''"></script>''); import_js_imported.push(script); } } }); })(jQuery);

Así que todo lo que necesitas hacer para importar JavaScript es:

$.import_js(''/path_to_project/scripts/somefunctions.js'');

También hice una prueba simple para esto en el Example .

Incluye un archivo main.js en el HTML principal y luego el script en main.js usa $.import_js() para importar un archivo adicional llamado included.js , que define esta función:

function hello() { alert("Hello world!"); }

Y justo después de incluir included.js , se llama a la función hello() y se recibe la alerta.

(Esta respuesta es en respuesta al comentario de e-satis).


Es posible generar dinámicamente una etiqueta JavaScript y adjuntarla a un documento HTML desde otro código JavaScript. Esto cargará el archivo JavaScript apuntado.

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");


Esto debería hacer:

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


Hay una buena noticia para ti. Muy pronto podrás cargar código JavaScript fácilmente. Se convertirá en una forma estándar de importar módulos de código JavaScript y formará parte de JavaScript en sí.

Simplemente tienes que escribir las condiciones de import cond from ''cond.js''; para cargar una macro llamada cond desde un archivo cond.js

Por lo tanto, no tiene que depender de ningún marco de JavaScript ni tiene que hacer llamadas Ajax explícitamente.

Referirse a:


La import declaración está en ECMAScript 6.

Sintaxis

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;


La mayoría de las soluciones mostradas aquí implican carga dinámica. En su lugar, estaba buscando un compilador que reuniera todos los archivos dependientes en un único archivo de salida. De la misma forma que los preprocesadores Less / Sass ocupan de CSS @import at-rule. Como no encontré nada decente de este tipo, escribí una herramienta simple para resolver el problema.

Así que aquí está el compilador, https://github.com/dsheiko/jsic , que reemplaza $import("file-path") con el contenido del archivo solicitado de forma segura. Aquí está el complemento Grunt correspondiente: https://github.com/dsheiko/grunt-jsic .

En la rama maestra de jQuery, simplemente concatenan archivos fuente atómicos en uno solo, comenzando con intro.js y terminando con outtro.js . Eso no me conviene, ya que no proporciona flexibilidad en el diseño del código fuente. Echa un vistazo a cómo funciona con jsic:

src / main.js

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

src / Form / Input / Tel.js

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

Ahora podemos ejecutar el compilador:

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

Y consigue el archivo combinado.

construir / main.js

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


Las versiones anteriores de JavaScript no importaban, incluían ni requerían, por lo que se han desarrollado muchos enfoques diferentes para este problema.

Pero desde 2015 (ES6), JavaScript ha tenido los módulos estándar ES6 para importar módulos en Node.js, que también es compatible con la mayoría de los navegadores modernos .

Para la compatibilidad con navegadores más antiguos, se pueden usar herramientas de build y / o transpilation .

Módulos ES6

Los módulos ECMAScript (ES6) se han admitido en Node.js desde v8.5, con el --experimental-modules . Todos los archivos involucrados deben tener la extensión .mjs .

// module.mjs export function hello() { return "Hello"; }

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

Módulos ECMAScript en navegadores

Los navegadores han tenido soporte para cargar módulos ECMAScript directamente (no se requieren herramientas como Webpack) since Safari 10.1, Chrome 61, Firefox 60 y Edge 16. Verifique el soporte actual en 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); }

Lea más en: since

Importaciones dinámicas en navegadores.

Las importaciones dinámicas permiten que el script cargue otros scripts según sea necesario:

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

Lea más en: https://developers.google.com/web/updates/2017/11/dynamic-import

Node.js requiere

El antiguo estilo de importación de módulos, todavía muy utilizado en Node.js, es el module.exports/require sistema module.exports/require .

// mymodule.js module.exports = { hello: function() { return "Hello"; } }

// server.js const myModule = require(''./mymodule''); let val = myModule.hello(); // val is "Hello"

Existen otras formas para que JavaScript incluya contenidos de JavaScript externos en los navegadores que no requieren preprocesamiento.

AJAX Cargando

Podría cargar un script adicional con una llamada AJAX y luego usar eval para ejecutarlo. Esta es la forma más sencilla, pero está limitada a su dominio debido al modelo de seguridad de la zona de pruebas de JavaScript. El uso de eval también abre la puerta a errores, trucos y problemas de seguridad.

jQuery Cargando

La biblioteca jQuery proporciona la funcionalidad de carga en una línea :

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

Carga dinámica de script

Podría agregar una etiqueta de script con la URL del script en el HTML. Para evitar la sobrecarga de jQuery, esta es una solución ideal.

El script puede incluso residir en un servidor diferente. Además, el navegador evalúa el código. La etiqueta <script> puede inyectarse en la página web <head> o insertarse justo antes de la etiqueta de cierre </body> .

Aquí hay un ejemplo de cómo esto podría funcionar:

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) }

Esta función agregará una nueva etiqueta <script> al final de la sección de encabezado de la página, donde el atributo src se establece en la URL que se asigna a la función como primer parámetro.

Ambas soluciones se discuten e ilustran en JavaScript Madness: Dynamic Script Loading .

Detectar cuándo se ha ejecutado el script.

Ahora, hay un gran problema que debes conocer. Hacer eso implica que carga el código de forma remota . Los navegadores web modernos cargarán el archivo y continuarán ejecutando su script actual porque cargan todo de forma asíncrona para mejorar el rendimiento. (Esto se aplica tanto al método jQuery como al método manual de carga dinámica de scripts).

Significa que si usa estos trucos directamente, no podrá usar su código recién cargado en la siguiente línea después de pedir que se cargue , ya que seguirá cargándose.

Por ejemplo: my_lovely_script.js contiene 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

Luego recargas la página pulsando F5 . ¡Y funciona! Confuso...

Entonces, ¿qué hacer al respecto?

Bueno, puedes usar el truco que sugiere el autor en el enlace que te di. En resumen, para las personas que tienen prisa, usa un evento para ejecutar una función de devolución de llamada cuando se carga el script. Así que puedes poner todo el código usando la biblioteca remota en la función de devolución de llamada. Por ejemplo:

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); }

Luego escribe el código que desea usar DESPUÉS de que el script se cargue en una función lambda :

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

Entonces corres todo eso

loadScript("my_lovely_script.js", myPrettyCode);

Tenga en cuenta que la secuencia de comandos puede ejecutarse después de que el DOM se haya cargado, o antes, según el navegador y si incluyó la línea script.async = false; . Hay un gran artículo sobre la carga de Javascript en general que discute esto.

Código fuente de combinación / preprocesamiento

Como se mencionó en la parte superior de esta respuesta, muchos desarrolladores utilizan herramientas de compilación / transpilación como Parcel, Webpack o Babel en sus proyectos, lo que les permite usar la próxima sintaxis de JavaScript, proporcionar compatibilidad con versiones anteriores de navegadores más antiguos, combinar archivos, minimizar, realizar división de código etc.


O en lugar de incluirlo en el tiempo de ejecución, use un script para concatenar antes de cargar.

Yo uso Sprockets (no sé si hay otros). Construye su código JavaScript en archivos separados e incluye comentarios que son procesados ​​por el motor de Sprockets como se incluye. Para el desarrollo, puede incluir archivos de forma secuencial, luego, para que la producción los combine ...

Ver también:


Otra forma, que en mi opinión es mucho más limpia, es hacer una solicitud Ajax síncrona en lugar de usar una etiqueta <script> . Que es también como Node.js maneja incluye.

Aquí hay un ejemplo usando 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); } }); }

Luego puede usarlo en su código como usualmente usaría un include:

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

Y poder llamar a una función desde el script requerido en la siguiente línea:

subscript.doSomethingCool();


Si alguien está buscando algo más avanzado, pruebe RequireJS . Obtendrá beneficios adicionales como la administración de dependencias, una mejor concurrencia y evitará la duplicación (es decir, recuperar un script más de una vez).

Puede escribir sus archivos JavaScript en "módulos" y luego hacer referencia a ellos como dependencias en otros scripts. O puede usar RequireJS como una solución simple "vaya a obtener este script".

Ejemplo:

Definir dependencias como módulos:

some-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 });

implementacion.js es su archivo "principal" de JavaScript que depende de some-dependency.js

require([''some-dependency''], function(dependency) { //Your script goes here //some-dependency.js is fetched. //Then your script is executed });

Extracto de GitHub README:

RequireJS carga archivos JavaScript simples así como módulos más definidos. Está optimizado para su uso en el navegador, incluso en un trabajador web, pero se puede usar en otros entornos de JavaScript, como Rhino y Node. Implementa la API del módulo asíncrono.

RequireJS utiliza etiquetas de script sin formato para cargar módulos / archivos, por lo que debería permitir una fácil depuración. Puede usarse simplemente para cargar archivos JavaScript existentes, de modo que puede agregarlo a su proyecto existente sin tener que volver a escribir sus archivos JavaScript.

...


Si quieres en JavaScript puro, puedes usar document.write .

document.write(''<script src="myscript.js" type="text/javascript"></script>'');

Si usa la biblioteca jQuery, puede usar el método $.getScript .

$.getScript("another_script.js");


Si su intención de cargar el archivo JavaScript está utilizando las funciones del archivo importado / incluido , también puede definir un objeto global y establecer las funciones como elementos de objeto. Por ejemplo:

global.js

A = {};

file1.js

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

archivo2.js

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

main.js

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

Solo debe tener cuidado al incluir scripts en un archivo HTML. El orden debe ser como en el siguiente:

<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>


Tal vez pueda usar esta función que encontré en esta página ¿Cómo incluyo un archivo JavaScript en un archivo JavaScript? :

function include(filename) { var head = document.getElementsByTagName(''head'')[0]; var script = document.createElement(''script''); script.src = filename; script.type = ''text/javascript''; head.appendChild(script) }


También puedes ensamblar tus scripts usando PHP :

Archivo 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


Tenía un problema simple, pero me desconcertaron las respuestas a esta pregunta.

Tuve que usar una variable (myVar1) definida en un archivo JavaScript (myvariables.js) en otro archivo JavaScript (main.js).

Para esto hice lo siguiente:

Cargó el código JavaScript en el archivo HTML, en el orden correcto, primero myvariables.js, luego main.js:

<html> <body onload="bodyReady();" > <script src="myvariables.js" > </script> <script src="main.js" > </script> <!-- Some other code --> </body> </html>

Archivo: myvariables.js

var myVar1 = "I am variable from myvariables.js";

Archivo: main.js

// ... function bodyReady() { // ... alert (myVar1); // This shows "I am variable from myvariables.js", which I needed // ... } // ...

Como viste, usé una variable en un archivo JavaScript en otro archivo JavaScript, pero no tuve que incluir una en otro. Solo necesitaba asegurarme de que el primer archivo JavaScript cargado antes del segundo archivo JavaScript, y las variables del primer archivo JavaScript estén accesibles en el segundo archivo JavaScript automáticamente.

Esto salvó mi día. Espero que esto ayude.


En lenguaje moderno seria

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


Mi método habitual es:

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); }

Funciona muy bien y no utiliza recarga de página para mí. He probado el método AJAX (una de las otras respuestas) pero no parece funcionar tan bien para mí.

Aquí hay una explicación de cómo funciona el código para aquellos que son curiosos: esencialmente, crea una nueva etiqueta de script (después de la primera) de la URL. Lo establece en modo asíncrono para que no bloquee el resto del código, pero llama a una devolución de llamada cuando el estado preparado (el estado del contenido que se va a cargar) cambia a ''cargado''.


Escribí un módulo simple que automatiza el trabajo de importar / incluir scripts de módulos en JavaScript. Para obtener una explicación detallada del código, consulte la publicación de blog que requiere JavaScript / 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); };


Este script agregará un archivo JavaScript en la parte superior de cualquier otra <script>etiqueta:

(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); })();


Hay muchas respuestas potenciales para esta pregunta. Mi respuesta está obviamente basada en varios de ellos. Esto es lo que terminé después de leer todas las respuestas.

El problema con $.getScripty realmente cualquier otra solución que requiera una devolución de llamada cuando se complete la carga es que si tiene varios archivos que lo usan y dependen unos de otros, ya no tendrá una manera de saber cuándo se han cargado todos los scripts (una vez que están anidados) en múltiples archivos).

Ejemplo:

file3.js

var f3obj = "file3"; // Define other stuff

archivo2.js:

var f2obj = "file2"; $.getScript("file3.js", function(){ alert(f3obj); // Use anything defined in file3. });

file1.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... });

Tiene razón cuando dice que podría especificar que Ajax se ejecute de forma síncrona o use XMLHttpRequest , pero la tendencia actual parece ser la de anular las solicitudes síncronas, por lo que es posible que no obtenga soporte completo para el navegador ahora o en el futuro.

Podría tratar de usar $.whenuna matriz de objetos diferidos, pero ahora está haciendo esto en cada archivo y el archivo2 se considerará cargado tan pronto como $.whense ejecute, no cuando se ejecute la devolución de llamada, por lo que el archivo1 continúa ejecutándose antes de que se cargue el archivo3 . Esto realmente todavía tiene el mismo problema.

Decidí ir hacia atrás en lugar de hacia adelante. Gracias document.writeln. Sé que es un tabú, pero siempre que se use correctamente, esto funciona bien. Terminas con un código que se puede depurar fácilmente, se muestra en el DOM correctamente y puede garantizar que las dependencias se carguen correctamente.

Por supuesto, puede usar $ ("body"). Append (), pero luego ya no puede depurar correctamente.

NOTA: debe usar esto solo mientras la página se está cargando, de lo contrario obtendrá una pantalla en blanco. En otras palabras, siempre coloque esto antes / fuera de document.ready . No lo he probado después de cargar la página en un evento de clic o algo así, pero estoy bastante seguro de que fallará.

Me gustó la idea de ampliar jQuery, pero obviamente no es necesario.

Antes de llamar document.writeln, verifica que el script no se haya cargado al evaluar todos los elementos del script.

Supongo que un script no se ejecuta completamente hasta que su document.readyevento se haya ejecutado. (Sé document.readyque no se requiere el uso, pero mucha gente lo usa y manejar esto es una garantía).

Cuando se carguen los archivos adicionales, las document.readydevoluciones de llamada se ejecutarán en el orden incorrecto. Para solucionar esto cuando se carga un script, el script que lo importó se vuelve a importar y se detiene la ejecución. Esto hace que el archivo de origen ahora tenga su document.readydevolución de llamada ejecutada después de cualquiera de los scripts que importa.

En lugar de este enfoque, podría intentar modificar el jQuery readyList, pero esto parecía una solución peor.

Solución:

$.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; } });

Uso:

File3:

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

Archivo2:

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

Archivo1:

$.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" });


He creado una función que le permitirá usar una palabrería similar a C # / Java para incluir un archivo JavaScript. Lo he probado un poco incluso desde dentro de otro archivo JavaScript y parece funcionar. Sin embargo, sí requiere jQuery para un poco de "magia" al final.

Puse este código en un archivo en la raíz de mi directorio de secuencias de comandos (lo nombré global.js, pero puedes usar lo que quieras. A menos que me equivoque y jQuery deberían ser las únicas secuencias de comandos requeridas en una página dada. Ten en cuenta esto En gran medida no se ha probado más allá de algún uso básico, por lo que puede o no haber problemas con la forma en que lo he hecho; úselo bajo su propio riesgo yadda yadda No soy responsable si arruina algo yadda yadda:

/** * @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); }


La @importsintaxis para lograr la importación de JavaScript similar a CSS es posible usando una herramienta como Mixture a través de su .mixtipo de archivo especial (ver here ). Me imagino que la aplicación simplemente usa uno de los métodos antes mencionados, aunque no lo sé.

De la documentación de la mezcla en .mixarchivos:

Los archivos de mezcla son simplemente archivos .js o .css con .mix. en el nombre del archivo. Un archivo mix simplemente extiende la funcionalidad de un estilo normal o un archivo de script y le permite importar y combinar.

Aquí hay un .mixarchivo de ejemplo que combina varios .jsarchivos en uno:

// 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";

La mezcla produce esto como scripts-global.jsy también como una versión minificada ( scripts-global.min.js).

Nota: No estoy afiliado de ninguna manera con Mixture, aparte de usarlo como una herramienta de desarrollo de front-end. Me encontré con esta pregunta al ver un .mixarchivo JavaScript en acción (en una de las placas de mezclas de Mixture) y estar un poco confundido ("puedes hacer esto", pensé para mí mismo). Luego me di cuenta de que era un tipo de archivo específico de la aplicación (algo decepcionante, de acuerdo). Sin embargo, imaginé que el conocimiento podría ser útil para otros.

ACTUALIZACIÓN : La mezcla ahora es gratuita (fuera de línea).

ACTUALIZACIÓN : La mezcla ahora está descontinuada. Todavía están disponibles versiones antiguas de mezclas .


Llegué a esta pregunta porque buscaba una forma sencilla de mantener una colección de complementos de JavaScript útiles. Después de ver algunas de las soluciones aquí, se me ocurrió esto:

  1. Configura un archivo llamado "plugins.js" (o extensions.js o lo que sea). Mantenga sus archivos de complementos junto con ese archivo maestro.

  2. plugins.js tendrá una matriz llamada "pluginNames []" que repetiremos en cada (), luego agregaremos una etiqueta a la cabeza para cada complemento

    // configurar la matriz para que se actualice cuando agregamos o eliminamos archivos de complemento var pluginNames = ["lettering", "fittext", "butterjam", etc.]; // una etiqueta de script para cada complemento $ .each (pluginNames, function () {$ (''head''). append ('''');});

  3. manualmente llame solo el archivo en su cabeza:
    <script src="js/plugins/plugins.js"></script>

Descubrí que a pesar de que todos los complementos se caían en la etiqueta de la cabeza de la forma en que debían hacerlo, el navegador no siempre los ejecutaba al hacer clic en la página o actualizar.

Descubrí que es más confiable simplemente escribir las etiquetas de script en un PHP incluido. Solo tienes que escribirlo una vez y eso es tanto trabajo como llamar al complemento usando JavaScript.


Mejor usar la forma jQuery . Para retrasar el evento listo, primera llamada $.holdReady(true). Ejemplo ( source ):

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


También hay Head.js . Es muy fácil tratar con:

head.load("js/jquery.min.js", "js/jquery.someplugin.js", "js/jquery.someplugin.css", function() { alert("Everything is ok!"); });

Como ve, es más fácil que Require.js y tan conveniente como el $.getScriptmétodo de jQuery . También tiene algunas características avanzadas, como carga condicional, detección de características y mucho más .


var js = document.createElement("script"); js.type = "text/javascript"; js.src = jsFilePath; document.body.appendChild(js);