JavaScript’de benzer bir şey var mı @import
CSS'de başka bir JavaScript dosyasının içine bir JavaScript dosyası eklemenizi sağlar?
JavaScript’de benzer bir şey var mı @import
CSS'de başka bir JavaScript dosyasının içine bir JavaScript dosyası eklemenizi sağlar?
Javascript'in eski sürümlerinin hiçbir ithalatı, içermemesi ya da gerektirmemesi nedeniyle, bu soruna birçok farklı yaklaşım geliştirilmiştir.
Ancak JavaScript'in son sürümlerinde standartlar var ES6 modülleri Bu, çoğu tarayıcı tarafından henüz desteklenmese de modülleri içe aktarma. Tarayıcı uygulamaları ile modülleri kullanan birçok kişi inşa etmek ve / veya transpilation Modüller gibi özelliklerle yeni sözdizimini kullanabilmeyi sağlayan araçlar.
Şu anda, ES6 Modülleri için tarayıcı desteğinin özellikle büyük olmadığını, ancak yolda olduğunu unutmayın. Göre Bu StackOverflow cevabıChrome 61, Firefox 54’te destekleniyorlar. dom.moduleScripts.enabled
yerleştirme about:config
) ve MS Edge 16, sadece Safari 10.1 ile bayraksız destek sağlar.
Bu nedenle, şu anda, kullanıcı için bu tarayıcı sürümlerini kullanması veya herhangi bir bayrağı etkinleştirmesine gerek kalmadan çalışacak geçerli JavaScript'e derleme ve / veya transpilasyon araçları kullanmanız gerekecektir.
ES6 Modülleri olağan olduğunda, bunları nasıl kullanacağınız aşağıda açıklanmıştır:
// module.js
export function hello() {
return "Hello";
}
// main.js
import {hello} from 'module'; // or './module'
let val = hello(); // val is "Hello";
Node.js şu anda bir module.exports / gerektirir sistemi. Kullanabilirsiniz babel
eğer isterseniz import
sözdizimi.
// mymodule.js
module.exports = {
hello: function() {
return "Hello";
}
}
// server.js
const myModule = require('./mymodule');
let val = myModule.hello(); // val is "Hello"
JavaScript’in ön işlem gerektirmeyen tarayıcılarda harici JavaScript içeriklerini içermesinin başka yolları da vardır.
Bir AJAX çağrısı ile ek bir komut dosyası yükleyebilir ve daha sonra kullanabilirsiniz. eval
onu çalıştırmak için. Bu en basit yoldur, ancak JavaScript sanal güvenlik modeli nedeniyle alan adınızla sınırlıdır. kullanma eval
ayrıca hatalara, korsanlara ve güvenlik sorunlarına kapı açar.
jQuery kütüphane yükleme işlevselliği sağlar tek satırda:
$.getScript("my_lovely_script.js", function() {
alert("Script loaded but not necessarily executed.");
});
HTML’ye komut dosyası URL’si olan bir komut dosyası etiketi ekleyebilirsiniz. JQuery'nin yükünü önlemek için bu ideal bir çözümdür.
Komut dosyası, farklı bir sunucuda bile bulunabilir. Ayrıca, tarayıcı kodu değerlendirir. <script>
etiket web sayfasına enjekte edilebilir <head>
veya kapanıştan hemen önce eklendi </body>
etiket.
Bunun nasıl çalışabileceğine dair bir örnek:
function dynamicallyLoadScript(url) {
var script = document.createElement("script"); // Make a script DOM node
script.src = url; // Set it's 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)
}
Bu işlev yeni eklenecek <script>
sayfanın baş bölümünün sonuna etiketle src
öznitelik, işleve ilk parametre olarak verilen URL'ye ayarlanır.
Bu çözümlerin her ikisi de tartışılmış ve gösterilmiştir. JavaScript Madness: Dinamik Script Yükleme.
Şimdi bilmeniz gereken büyük bir sorun var. Bunu yapmak şunu ima eder uzaktan kodu yüklersin. Modern web tarayıcıları, dosyayı yükleyecek ve mevcut komut dosyanızı yürütmeye devam edecekler çünkü performanslarını iyileştirmek için herşeyi senkronize olmayan şekilde yüklerler. (Bu, hem jQuery yöntemi hem de manuel dinamik komut dosyası yükleme yöntemi için geçerlidir.)
Bu hileleri doğrudan kullanırsanız, Yüklendikten sonra yeni yüklenen kodunuzu bir sonraki satıra kullanamazsınızÇünkü hala yüklenecek.
Örneğin: my_lovely_script.js
içeren 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
Ardından, sayfanın yüklenmesini yeniden yüklersiniz F5. Ve çalışıyor! Kafa karıştırıcı...
Peki bu konuda ne yapmalı?
Peki, size verdiğim linkte yazarın önerdiği kesmeyi kullanabilirsiniz. Özetle, acelesi olan insanlar için, betik yüklendiğinde geri arama işlevini çalıştırmak için bir olay kullanır. Böylece tüm kodu geri arama işlevindeki uzak kütüphaneyi kullanarak koyabilirsiniz. Örneğin:
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);
}
Sonra kullanmak istediğiniz kodu yazarsınız. lambda işlevi:
var myPrettyCode = function() {
// Here, do whatever you want
};
Öyleyse sen hepsini çalıştır.
loadScript("my_lovely_script.js", myPrettyCode);
Betiğin, DOM'a yüklendikten sonra veya tarayıcıya bağlı olup olmadığını ve satırın dahil olup olmadığını belirleyebileceğini unutmayın. script.async = false;
. Orada bir Genel olarak Javascript yüklemesiyle ilgili harika bir makale bunu tartışıyor.
Bu yanıtın en üstünde de belirtildiği gibi, birçok geliştirici artık projelerinde WebPack, Babel veya Gulp gibi yapı / transpilasyon araçlarını kullanıyor, yeni sözdizimi ve destek modüllerini daha iyi kullanabilmelerine, dosyaları birleştirebilmelerine, küçültebilmelerine vb.
Herhangi biri daha gelişmiş bir şey arıyorsanız, deneyin RequireJS. Bağımlılık yönetimi, daha iyi eşzamanlılık gibi ek avantajlar elde edersiniz ve çoğaltılmayı önlersiniz (yani, bir komut dosyasını birden çok kez alma).
JavaScript dosyalarınızı "modüller" içine yazabilir ve daha sonra diğer komut dosyalarındaki bağımlılıklar olarak gönderebilirsiniz. Ya da RequireJS'yi basitçe "bu betiği al" çözümü olarak kullanabilirsiniz.
Örnek:
Bağımlılıkları modüller olarak tanımlayın:
Bazı-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 bağlı "ana" JavaScript dosyanızdır Bazı-dependency.js
require(['some-dependency'], function(dependency) {
//Your script goes here
//some-dependency.js is fetched.
//Then your script is executed
});
Alıntıdan GitHub README:
RequireJS, daha fazla tanımlanmış olduğu gibi düz JavaScript dosyalarını yükler modüller. Web dahil olmak üzere tarayıcı içi kullanım için optimize edilmiştir Çalışan, ancak diğer JavaScript ortamlarında kullanılabilir, Gergedan ve Düğüm. Eşzamansız Modül API'sini uygular.
RequireJS, modülleri / dosyaları yüklemek için düz komut etiketlerini kullanır. Kolay hata ayıklamaya olanak tanır. Mevcut yüklemek için basitçe kullanılabilir JavaScript dosyaları var olan projeye eklemeden ekleyebilirsiniz JavaScript dosyalarınızı tekrar yazmanız gerekiyor.
...
Aslında orada olduğu JavaScript dosyasını yüklemek için bir yol değil Eşzamansız olarak, yükledikten hemen sonra yeni yüklediğiniz dosyada bulunan işlevleri kullanabilir ve sanırım tüm tarayıcılarda çalışır.
Kullanmalısın jQuery.append()
üzerinde <head>
sayfanızın öğesi, yani:
$("head").append('<script type="text/javascript" src="' + script + '"></script>');
Ancak, bu yöntemde ayrıca bir sorun var: içe aktarılan JavaScript dosyasında bir hata olursa, kundakçı (ve ayrıca Firefox Error Console ve Chrome Geliştirici Araçları yanı sıra) yanlış yerini bildirecektir, bu çok büyük bir sorundur (eğer) hatalar çok (yani) hataları izlemek için Firebug kullanırsanız. Firebug, yeni yüklenen dosyayı herhangi bir nedenle bilmez, bu nedenle bu dosyada bir hata oluşursa, ana bilgisayarınızda gerçekleştiğini bildirir. HTML Dosya ve hatanın gerçek nedenini bulmakta zorlanacaksınız.
Ama bu sizin için bir problem değilse, o zaman bu yöntem işe yarayacaktır.
Aslında adında bir jQuery eklentisi yazdım $ .import_js () Bu yöntemi kullanır:
(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);
Yani, JavaScript'i içe aktarmak için tek yapmanız gereken:
$.import_js('/path_to_project/scripts/somefunctions.js');
Bunun için de basit bir test yaptım Örnek.
İçerir bir main.js
ana HTML'de dosya ve daha sonra komut dosyası main.js
kullanımları $.import_js()
adında ek bir dosya almak için included.js
Bu işlevi tanımlayan:
function hello()
{
alert("Hello world!");
}
Ve sağladıktan sonra included.js
, hello()
işlev çağrılır ve uyarı alırsınız.
(Bu cevap, e-satis 'yorumuna cevaptır).
Başka bir şekilde, benim düşüncem daha temiz, bir kullanarak yerine bir eşzamanlı Ajax istek yapmaktır <script>
etiket. Bu da nasıl node.js kolları içerir.
İşte jQuery'yi kullanarak bir örnek:
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);
}
});
}
Daha sonra, kodunuzda genellikle bir include kullandığınız gibi kullanabilirsiniz:
require("/scripts/subscript.js");
Ve bir sonraki satırdaki gerekli komut dosyasından bir işlevi çağırabilmek için:
subscript.doSomethingCool();
Senin için iyi bir haber var. Çok yakında JavaScript kodunu kolayca yükleyebileceksiniz. JavaScript kodunun modüllerini içe aktarmanın standart bir yolu olacak ve temel JavaScript'in kendisinin bir parçası olacak.
Sadece yazmak zorundasın import cond from 'cond.js';
adlı bir makro yüklemek cond
bir dosyadan cond.js
.
Yani, herhangi bir JavaScript çerçevesine güvenmek zorunda değilsiniz, ya da açıkça yapmak zorunda değilsiniz ajax çağırır.
Bakın:
Bir JavaScript etiketini dinamik olarak oluşturmak ve HTML dokümanı için diğer JavaScript kodunun içinden eklemek mümkündür. Bu, hedeflenen JavaScript dosyasını yükleyecektir.
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");
Beyan import
ECMAScript 6'da.
Sözdizimi
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;
Belki bu sayfada bulduğum bu işlevi kullanabilirsiniz. JavaScript dosyasına nasıl bir JavaScript dosyası ekleyebilirim?:
function include(filename)
{
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = filename;
script.type = 'text/javascript';
head.appendChild(script)
}
Burada bir senkron versiyon jQuery olmadan:
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);
}
Bu çalışma alanları arası alanı elde etmek için sunucunun ayarlanması gerektiğini unutmayın. allow-origin
cevabında başlık.
Sadece bu JavaScript kodunu yazdım ( Prototip için DOM manipülasyonu):
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);
}
});
})();
Kullanımı:
<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>
İşte, Facebook'un her yerde olduğu gibi düğmesinin genelleştirilmiş hali gibi:
<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>
Facebook için çalışıyorsa, sizin için çalışacaktır.
İlk önce neden aradığımızın nedeni script
yerine head
veya body
bazı tarayıcılar eksikse bir tane oluşturmaz, ancak bir script
eleman - bu bir. da daha fazlasını oku http://www.jspatterns.com/the-ridiculous-case-of-adding-a-script-element/.