자바스크립트 파일을 안정적이고 동적으로 로드하려면 어떻게 해야 할까요? 이는 모듈이나 컴포넌트를 구현하는 데 사용할 수 있으며, 이 컴포넌트는 초기화될 때 필요한 모든 JavaScript 라이브러리 스크립트를 필요에 따라 동적으로 로드합니다.
컴포넌트를 사용하는 클라이언트는 이 컴포넌트를 구현하는 모든 라이브러리 스크립트 파일을 로드할 필요가 없으며(웹 페이지에 스크립트
태그를 수동으로 삽입할 필요도 없음), 기본
컴포넌트 스크립트 파일만 로드하면 됩니다.
**주류 자바스크립트 라이브러리(프로토타입, jQuery 등)는 이 작업을 어떻게 수행하나요? 이러한 도구는 여러 자바스크립트 파일을 재배포 가능한 단일 버전의 스크립트 파일로 병합하나요? 아니면 보조 라이브러리 스크립트의 동적 로딩을 수행하나요?
이 질문에 추가 질문이 있습니다: **동적으로 포함된 자바스크립트 파일이 로드된 후 이벤트를 처리하는 방법이 있나요? 프로토타입에는 문서 전체 이벤트를 위한 document.observe
가 있습니다. 예시:
document.observe("dom:loaded", function() {
// initially hide all containers for tab content
$$('div.tabcontent').invoke('hide');
});
**스크립트 요소에 사용할 수 있는 이벤트는 무엇인가요?
동적 스크립트입니다 쓸 수 있습니다 태그 (using 프로토타입).
new Element("script", {src: "myBigCodeLibrary.js", type: "text/javascript"});
우리는 종종 하는 바로 그 선을 따라 스맥랜드의 lionbridge 코드 진단트리로 write something like:
if (iNeedSomeMore) {
Script.load("myBigCodeLibrary.js"); // includes code for myFancyMethod();
myFancyMethod(); // cool, no need for callbacks!
}
There is a 필요 없이 콜백 스크립트입니다 종속물과의 투입할 수 있는 현명한 방법입니다. 동기식 통해 AJAX 요청을 할 당기십시오 스크립트입니다 됩니다 및 평가 스크립트입니다 켜짐이 글로벌 수준.
프로토타입 (prototype) 을 사용할 경우 스크리프스트로이드 방법은 다음과 같습니다.
var Script = {
_loadedScripts: [],
include: function(script) {
// include script only once
if (this._loadedScripts.include(script)) {
return false;
}
// request file synchronous
var code = new Ajax.Request(script, {
asynchronous: false,
method: "GET",
evalJS: false,
evalJSON: false
}).transport.responseText;
// eval code on global level
if (Prototype.Browser.IE) {
window.execScript(code);
} else if (Prototype.Browser.WebKit) {
$$("head").first().insert(Object.extend(
new Element("script", {
type: "text/javascript"
}), {
text: code
}
));
} else {
window.eval(code);
}
// remember included script
this._loadedScripts.push(script);
}
};
Javascript 에서 필요 없는 가져오기의 포함 /, / 수축됐는데 두 가지 주요 성과를 올릴 수 있는 그리웠댔지:
1 - AJAX call it 를 불러올 수 있습니다 다음 평가.
하지만 이것이 가장 직설적으로 it& # 39 의 Javascript 를 사용하여 안전 때문에 eval 은 제한된 데이터베이스에구성원을 도메인 설정 및 버그 수정 및 문을 여는 hacks.
2 - 추가 스크랩트 태그로 HTML 에서 uirl 스크립트입니다.
가장 좋은 방법은 말해둘꼐요 검색하기를. 외국 서버 및 it& 단계부터 스크립트입니다 불러올 수 있습니다; s # 39 를 사용할 때 청소하십시오 있지만브라우저에 파서에서 평가하십시오 코드입니다. 이 <, 스크립트입니다 /> 올릴 수 있습니다. 머리에 태그번호 또는 웹 페이지의 하단에 바디입니다.
이 솔루션은 모두 함께 볼 수 있습니다.
이제 알면 큰 문제가 없다고 합니다. 그렇게 할 수 있음을 너회가 원격으로요 읽어들입니다 코드입니다. 현대의 모든 웹 브라우저에서 실행 파일을 로드할 수 있기 때문에, 항상 비동기적으로 현재 스크립트입니다 로드하십시오 향상시키십시오 문제는 성능이었죠.
즉, 이러한 요령 직접 사용하는 경우, 당신은 won& t # 39, 새로 로드됨 코드를 사용할 수 있습니다 다음 줄 수 있기 때문에 여전히 그런 후에는 로드되었는지 로드중 됩니다.
E. G: my_lovely_script.js map_layer 미스페로비치
var js = document.createElement("script");
js.type = "text/javascript";
js.src = jsFilePath;
document.body.appendChild(js);
var s = new MySuperObject();
Error : MySuperObject is undefined
그런 다음 페이지를 다시 로드하십시오 타격 F5. 및 작동하잖아! 혼란스럽다.
그래서 어떻게 해야 할까?
뭐, 해킹 저자는 에 줬잖아 https://partner. 제안됩니다 사용할 수 있습니다. 요약하자면, 콜백 함수를 사용하여 실행할 수 있는 사람들을 위해 빨리 en 이벤트 때, 그는 스크립트입니다 로드되었는지. 넣을 수 있도록 모든 코드 라이브러리를 사용하여 원격입니다 의 콜백 함수. E. G:
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);
}
그런 후 사용할 수 있는 코드 기록하십시오 스크립트입니다 로드되었는지 람다 함수.
var myPrettyCode = function() {
// here, do what ever you want
};
그런 다음 모두실행 다음과 같이 밝혔다:
loadScript("my_lovely_script.js", myPrettyCode);
Ok, I got it. 그러나 it& # 39 의 통증 진저한테 쓸 것.
그렇다면 으로 사용할 수 있도록 하는 것이 있다, 항상 자유 jQuery 프레임워크입니다 돼 한 줄로 못하며창조된 그렇네.
$.getScript("my_lovely_script.js", function() {
alert("Script loaded and executed.");
// here you can use anything you defined in the loaded script
});
사용 훨씬 더 복잡한 버전 최근 와 jQuery:
<script src="scripts/jquery.js"></script>
<script>
var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
var $head = $("head");
for (var i = 0; i < js.length; i++) {
$head.append("<script src=\"" + js[i] + "\"></scr" + "ipt>");
}
</script>
나는 모든 면에서 큰 있지만브라우저에 테스트되었습니다 된다고 합니다. IE6/7, 파이어폭스, 사파리, 오페라.
<script>
var js = ["scripts/jquery.dimensions.js", "scripts/shadedborder.js", "scripts/jqmodal.js", "scripts/main.js"];
for (var i = 0, l = js.length; i < l; i++) {
document.getElementsByTagName("head")[0].innerHTML += ("<script src=\"" + js[i] + "\"></scr" + "ipt>");
}
</script>
저는 기본적으로 Adam과 동일한 작업을 수행했지만 작업을 완료하기 위해 헤드 태그에 추가하도록 약간의 수정을 가했습니다. 스크립트 파일과 CSS 파일을 모두 처리하는 include 함수(아래 코드)를 간단히 만들었습니다.
이 함수는 스크립트 또는 CSS 파일이 이미 동적으로 로드되지 않았는지 확인합니다. 이 함수는 손으로 코딩한 값을 확인하지 않으며 더 좋은 방법이 있었을 수도 있지만 목적에 부합했습니다.
function include( url, type ){
// First make sure it hasn't been loaded by something else.
if( Array.contains( includedFile, url ) )
return;
// Determine the MIME-type
var jsExpr = new RegExp( "js$", "i" );
var cssExpr = new RegExp( "css$", "i" );
if( type == null )
if( jsExpr.test( url ) )
type = 'text/javascript';
else if( cssExpr.test( url ) )
type = 'text/css';
// Create the appropriate element.
var tag = null;
switch( type ){
case 'text/javascript' :
tag = document.createElement( 'script' );
tag.type = type;
tag.src = url;
break;
case 'text/css' :
tag = document.createElement( 'link' );
tag.rel = 'stylesheet';
tag.type = type;
tag.href = url;
break;
}
// Insert it to the <head> and the array to ensure it is not
// loaded again.
document.getElementsByTagName("head")[0].appendChild( tag );
Array.add( includedFile, url );
}
다른 멋진 대답
$.getScript("my_lovely_script.js", function(){
alert("Script loaded and executed.");
// here you can use anything you defined in the loaded script
});
다음은 제가 찾은 코드 예시입니다... 더 좋은 방법이 있으신가요?
function include(url)
{
var s = document.createElement("script");
s.setAttribute("type", "text/javascript");
s.setAttribute("src", url);
var nodes = document.getElementsByTagName("*");
var node = nodes[nodes.length -1].parentNode;
node.appendChild(s);
}
그냥 yui 의 3 에 대해 알게 되고 있는 유용한 기능을 (당시 미리봅니다 릴리스에는 먹어서나 사용 가능). 쉽게 삽입할 수 있으며, yui 의 라이브러리보다는 " external" 종속물과의 수 있습니다. 모듈 (찾고 너희는너희가 없이 너무 코드: Yui 의 로더입니다.
또한 두 번째 질문에 대한 답을 호출되는 함수는 즉시 개외부 모듈에서는 로드되었는지.
예:
YUI({
modules: {
'simple': {
fullpath: "http://example.com/public/js/simple.js"
},
'complicated': {
fullpath: "http://example.com/public/js/complicated.js"
requires: ['simple'] // <-- dependency to 'simple' module
}
},
timeout: 10000
}).use('complicated', function(Y, result) {
// called as soon as 'complicated' is loaded
if (!result.success) {
// loading failed, or timeout
handleError(result.msg);
} else {
// call a function that needs 'complicated'
doSomethingComplicated(...);
}
});
완벽하게 협력했습니다 가져다줄래요 계시한하나님께 관리 종속물과의 장점이 있습니다. Yui 의 문서 참조 ui_policytable_java_spe_policy 스케줄표의 예와 함께 yui 의 2.
여기 이 파일을 찾을 수 있습니다. 니클라우데지제스
/** include - including .js files from JS - [email protected] - 2005-02-09
** Code licensed under Creative Commons Attribution-ShareAlike License
** http://creativecommons.org/licenses/by-sa/2.0/
**/
var hIncludes = null;
function include(sURI)
{
if (document.getElementsByTagName)
{
if (!hIncludes)
{
hIncludes = {};
var cScripts = document.getElementsByTagName("script");
for (var i=0,len=cScripts.length; i < len; i++)
if (cScripts[i].src) hIncludes[cScripts[i].src] = true;
}
if (!hIncludes[sURI])
{
var oNew = document.createElement("script");
oNew.type = "text/javascript";
oNew.src = sURI;
hIncludes[sURI]=true;
document.getElementsByTagName("head")[0].appendChild(oNew);
}
}
}
>. 더 나은 방법이 투명지에 누구?
저는 그냥 스크립트입니다 추가한 다음 추가 몸에 약간만이라도 간소화하는지 마지막 페이지에서 노드입니다. 이건 어때.
function include(url) {
var s = document.createElement("script");
s.setAttribute("type", "text/javascript");
s.setAttribute("src", url);
document.body.appendChild(s);
}
A , 스크립트입니다 스케쳐내 동기화됨 헤드입니다 태그이고, HTML 로 직접 텍스트를 스크립트입니다 로드중 추가해야 합니다 Src 정보기술 (it) 을 추가 < 스크립트입니다 " myscript.js" >,, = 비동기 트리거합니다 로드. 외부 파일을 동시에 스어 로드하기에 스크립트입니다 의 텍스트를 사용합니다. 아래 빠른 샘플 (이는 다른 답을 부품을 사용하여 이 및 기타 게시물):
/*sample requires an additional method for array prototype:*/
if (Array.prototype.contains === undefined) {
Array.prototype.contains = function (obj) {
var i = this.length;
while (i--) { if (this[i] === obj) return true; }
return false;
};
};
/*define object that will wrap our logic*/
var ScriptLoader = {
LoadedFiles: [],
LoadFile: function (url) {
var self = this;
if (this.LoadedFiles.contains(url)) return;
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
self.LoadedFiles.push(url);
self.AddScript(xhr.responseText);
} else {
if (console) console.error(xhr.statusText);
}
}
};
xhr.open("GET", url, false);/*last parameter defines if call is async or not*/
xhr.send(null);
},
AddScript: function (code) {
var oNew = document.createElement("script");
oNew.type = "text/javascript";
oNew.textContent = code;
document.getElementsByTagName("head")[0].appendChild(oNew);
}
};
/*Load script file. ScriptLoader will check if you try to load a file that has already been loaded (this check might be better, but I'm lazy).*/
ScriptLoader.LoadFile("Scripts/jquery-2.0.1.min.js");
ScriptLoader.LoadFile("Scripts/jquery-2.0.1.min.js");
/*this will be executed right after upper lines. It requires jquery to execute. It requires a HTML input with id "tb1"*/
$(function () { alert($('#tb1').val()); });
그건 정말 파선-짧은, 단순하고, 관리할 수 있습니다! ]
// 3rd party plugins / script (don't forget the full path is necessary)
var FULL_PATH = '', s =
[
FULL_PATH + 'plugins/script.js' // Script example
FULL_PATH + 'plugins/jquery.1.2.js', // jQuery Library
FULL_PATH + 'plugins/crypto-js/hmac-sha1.js', // CryptoJS
FULL_PATH + 'plugins/crypto-js/enc-base64-min.js' // CryptoJS
];
function load(url)
{
var ajax = new XMLHttpRequest();
ajax.open('GET', url, false);
ajax.onreadystatechange = function ()
{
var script = ajax.response || ajax.responseText;
if (ajax.readyState === 4)
{
switch(ajax.status)
{
case 200:
eval.apply( window, [script] );
console.log("library loaded: ", url);
break;
default:
console.log("ERROR: library not loaded: ", url);
}
}
};
ajax.send(null);
}
// initialize a single load
load('plugins/script.js');
// initialize a full load of scripts
if (s.length > 0)
{
for (i = 0; i < s.length; i++)
{
load(s[i]);
}
}
이 코드는 기능 추가 기능을 할 수 있는 example 앨리어스가 파선-짧은 대한 전폭적인 지원을 위한 (또는 지정된) 플랫폼.
/*
대한 (var 스크립트입니다 라이브러리) { $ (# 39, & # 39, head&) 지아펜드 (& # 39 < 스크립트입니다 유형 = " text/javascript";;; src = ", & # 39. + dirPath + 라이브러리란 [스크립트입니다] + & # 39, & # 39 /script> < > ";;;;). }
<script type="text/javascript" src="project.library.js"></script>
Here 는 간단한 1 개는 콜백하는 및 IE 지원:
function loadScript(url, callback) {
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState) { //IE
script.onreadystatechange = function () {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function () {
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
loadScript("https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function () {
//jQuery loaded
console.log('jquery loaded');
});
이 질문에 대한 답이 그러니까말이야 내 말 좀 있지만, 이것은 멋지구리해요 기사로 www.html5rocks.com - [심층 양국 모두 이 곳에 로드을 스크립트입니다] [1].
[1]: https://www.html5rocks.com/en/tutorials/speed/script-loading/ # 목차 공격적인 최적화
이와 관련 있는 것이 가장 좋은 방법은 그 기사를 결론을 브라우저 지원, JavaScript 파일을 렌더링 () 은 다음과 같은 방법으로 동적으로 로드할 차단하지 않고 컨텐츠:
[
'script1.js',
'script2.js',
'script3.js',
'script4.js'
].forEach(function(src) {
var script = document.createElement('script');
script.src = src;
script.async = false;
document.head.appendChild(script);
});
, 사양명세 이제 밝혔습니다. 함께 다운로드하십시오 실행하십시오 대로 위해 모든 다운로드하십시오.
Firefox <. "비동기" 이 뭔지, 오페라 says:* 3.6tb 안 것은 아니지만, 난 또 무슨 일이 있어도 너무 autoexec. 스크립트에만 통해 JS 순서대로 덧붙였다.
사파리 5.0 says:* 이해할 수 있지만, 이를 통해 "비동기" 설정 "거짓" JS 모를 일이다. 나는 대로, 어떤 스크립트에 실행하십시오 있는모든 오더할.
IE <. "비동기") 이 있는데, 약 10 says:* 전혀 모르고 사용하는 방법을 "모리디국가창레."
다른 모든 says:* 난 친구, 우리거야 이렇게 이 책의.
현재 전체 코드와 IE <. 10 workaround:*
var scripts = [
'script1.js',
'script2.js',
'script3.js',
'script4.js'
];
var src;
var script;
var pendingScripts = [];
var firstScript = document.scripts[0];
// Watch scripts load in IE
function stateChange() {
// Execute as many scripts in order as we can
var pendingScript;
while (pendingScripts[0] && pendingScripts[0].readyState == 'loaded') {
pendingScript = pendingScripts.shift();
// avoid future loading events from this script (eg, if src changes)
pendingScript.onreadystatechange = null;
// can't just appendChild, old IE bug if element isn't closed
firstScript.parentNode.insertBefore(pendingScript, firstScript);
}
}
// loop through our script urls
while (src = scripts.shift()) {
if ('async' in firstScript) { // modern browsers
script = document.createElement('script');
script.async = false;
script.src = src;
document.head.appendChild(script);
}
else if (firstScript.readyState) { // IE<10
// create a script and add it to our todo pile
script = document.createElement('script');
pendingScripts.push(script);
// listen for state changes
script.onreadystatechange = stateChange;
// must set src AFTER adding onreadystatechange listener
// else we’ll miss the loaded event for cached scripts
script.src = src;
}
else { // fall back to defer
document.write('<script src="' + src + '" defer></'+'script>');
}
}
!function(e,t,r){function n(){for(;d[0]&&"loaded"==d[0][f];)c=d.shift(),c[o]=!i.parentNode.insertBefore(c,i)}for(var s,a,c,d=[],i=e.scripts[0],o="onreadystatechange",f="readyState";s=r.shift();)a=e.createElement(t),"async"in i?(a.async=!1,e.head.appendChild(a)):i[f]?(d.push(a),a[o]=n):e.write("<"+t+' src="'+s+'" defer></'+t+">"),a.src=s}(document,"script",[
"//other-domain.com/1.js",
"2.js"
])
여기서 함수 로드하기에 간단한 예를 JS 파일. 관련 방향점:
var getScriptOnce = function() {
var scriptArray = []; //array of urls (closure)
//function to defer loading of script
return function (url, callback){
//the array doesn't have such url
if (scriptArray.indexOf(url) === -1){
var script=document.createElement('script');
script.src=url;
var head=document.getElementsByTagName('head')[0],
done=false;
script.onload=script.onreadystatechange = function(){
if ( !done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') ) {
done=true;
if (typeof callback === 'function') {
callback();
}
script.onload = script.onreadystatechange = null;
head.removeChild(script);
scriptArray.push(url);
}
};
head.appendChild(script);
}
};
}();
끝 - < 스니핏 >;!
이제 간단히 사용한다.
getScriptOnce("url_of_your_JS_file.js");