javascript - 호출 - 자바스크립트 다른 파일 변수




다른 JavaScript 파일에 JavaScript 파일을 포함하려면 어떻게합니까? (20)

JavaScript 태그를 동적으로 생성하여 다른 JavaScript 코드 내부에서 HTML 문서에 추가 할 수 있습니다. 그러면 대상 JavaScript 파일이로드됩니다.

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

다른 JavaScript 파일 안에 JavaScript 파일을 포함시킬 수있는 CSS의 @import 와 비슷한 JavaScript가 있습니까?


JavaScript 파일을로드하려는 의도가 가져온 / 포함 된 파일의 함수를 사용하는 경우 전역 객체를 정의하고 해당 함수를 객체 항목으로 설정할 수도 있습니다. 예를 들면 :

global.js

A = {};

file1.js

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

file2.js

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

main.js

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

HTML 파일에 스크립트를 포함 할 때 조심해야합니다. 순서는 다음과 같아야합니다.

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

나는 간단한 문제가 있었지만이 질문에 대한 답변에 당황 스러웠다.

다른 JavaScript 파일 (main.js)에서 하나의 JavaScript 파일 (myvariables.js)에 정의 된 변수 (myVar1)를 사용해야했습니다.

이것을 위해 나는 아래와 같이했다.

자바 스크립트 코드를 HTML 파일의 올바른 순서 (myvariables.js)로로드 한 다음 main.js :

<html>
    <body onload="bodyReady();" >

        <script src="myvariables.js" > </script>
        <script src="main.js" > </script>

        <!-- Some other code -->
    </body>
</html>

파일 : myvariables.js

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

파일 : main.js

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

당신이 보았 듯이, 하나의 JavaScript 파일에서 다른 JavaScript 파일의 변수를 사용했지만 다른 것을 포함 할 필요가 없었습니다. 첫 번째 JavaScript 파일이 두 번째 JavaScript 파일 앞에로드되고 두 번째 JavaScript 파일에서 첫 번째 JavaScript 파일의 변수에 자동으로 액세스 할 수있게해야했습니다.

이것은 나의 하루를 구했다. 이게 도움이 되길 바란다.


다음은 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);
}

이 작동 교차 도메인을 얻으려면 서버가 응답에 allow-origin header를 설정해야합니다.


또 다른 방법은, 내 의견으로는 훨씬 더 깨끗한, <script> 태그를 사용하는 대신 동기식 Ajax 요청을하는 것이다. Node.js 가 처리하는 방법도 마찬가지입니다.

다음은 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);
        }
    });
}

일반적으로 include를 사용하는 것처럼 코드에서 사용할 수 있습니다.

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

다음 줄에서 필요한 스크립트의 함수를 호출 할 수 있어야합니다.

subscript.doSomethingCool(); 

또는 런타임에 포함하기보다는 스크립트를 사용하여 업로드하기 전에 연결하십시오.

나는 Sprockets 사용한다. (다른 사람들이 있는지 나는 모른다.) 별도의 파일에 JavaScript 코드를 작성하고 Sprockets 엔진에서 처리 한 주석을 포함시킵니다. 개발을 위해 파일을 순차적으로 포함 할 수 있으며, 제작을 위해 파일을 병합 할 수 있습니다.

참조 :


방금이 JavaScript 코드를 작성했습니다 ( DOM 조작을 위해 Prototype 사용).

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

용법:

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

요지 : http://gist.github.com/284442 .


순수한 JavaScript로 원하면 document.write 를 사용할 수 있습니다.

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

jQuery 라이브러리를 사용하는 경우 $.getScript 메소드를 사용할 수 있습니다.

$.getScript("another_script.js");


여기에 표시된 대부분의 솔루션은 동적로드를 의미합니다. 나는 의존 파일을 하나의 출력 파일로 모으는 컴파일러 대신에 찾고있었습니다. Less / Sass 전 처리기와 마찬가지로 CSS @import at-rule을 처리합니다. 나는 이런 종류의 점잖은 것을 찾지 못했기 때문에이 문제를 해결하는 간단한 도구를 썼다.

따라서 $import("file-path") 를 요청 된 파일 내용으로 안전하게 대체하는 컴파일러 https://github.com/dsheiko/jsic 있습니다. 다음은 해당 Grunt 플러그인입니다. https://github.com/dsheiko/grunt-jsic .

jQuery 마스터 브랜치에서, 그들은 단순히 원시 소스 파일을 intro.js 시작하고 intro.js 로 끝나는 단일 파일로 연결합니다. 그것은 소스 코드 디자인에 유연성을 제공하지 않으므로 저에게 적합하지 않습니다. jsic과 함께 작동하는지 확인하십시오.

src / main.js

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

src / 양식 / 입력란 / Tel.js

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

이제 컴파일러를 실행할 수 있습니다.

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

결합 된 파일 가져 오기

build / main.js

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

이렇게해야합니다 :

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

좋은 소식이 있습니다. 곧 자바 스크립트 코드를 쉽게로드 할 수 있습니다. JavaScript 코드의 모듈을 가져 오는 표준 방법이 될 것이며 핵심 자바 스크립트 자체의 일부가 될 것입니다.

import cond from 'cond.js'; 를 작성하기 만하면됩니다 import cond from 'cond.js'; cond.js 파일에서 cond 라는 매크로를로드합니다.

따라서 JavaScript 프레임 워크에 의존 할 필요가 없으며 Ajax 호출을 명시 적으로 만들어야 할 필요가 없습니다.

인용하다:


웹 근로자 를 사용하고 있고 작업자의 범위에 추가 스크립트를 포함하려는 경우 head 태그에 스크립트를 추가하는 것과 관련하여 제공되는 다른 대답은 작동하지 않습니다.

다행스럽게도 웹 워커는 독자적인 importScripts 함수를 가지고 있습니다.이 함수는 웹 워커 (Web Worker)의 범위에서 전역 함수이며, 브라우저 자체 에 고유 합니다.

또는 두 번째로 높은 질문에 대한 답변으로 두 번째로 높은 점수를 얻은 RequireJS 는 웹 작업자 내에서 스크립트를 포함하여 처리 할 수 ​​있습니다 ( importScripts 자체를 호출 할 수 있지만 다른 유용한 기능이 있음).


내 평소 방법은 :

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

그것은 잘 작동하고 나를 위해 페이지를 다시로드하지 않습니다. 나는 AJAX 메서드 (다른 답변 중 하나)를 시도했지만 멋지게 작동하지 않는다.

다음은 흥미로운 코드에 대한 코드 작동 방식입니다. 기본적으로 URL의 첫 번째 스크립트 태그 다음에 새 스크립트 태그가 생성됩니다. 비동기 모드로 설정하여 나머지 코드는 차단하지 않지만 readyState (로드 할 내용의 상태)가 'loaded'로 변경되면 콜백을 호출합니다.


Head.jsHead.js . 처리하기가 매우 쉽습니다.

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

보시다시피, Require.js보다 쉽고 jQuery의 $.getScript메소드 만큼 편리합니다 . 또한 조건부로드, 특징 검출과 같은 몇 가지 고급 기능이 훨씬 더 .


@importCSS와 같은 자바 스크립트 가져 오기를 달성하기위한 구문은 그들의 특별한 통해 혼합물 같은 도구를 사용 가능하다 .mix파일 형식 (참조 here ). 응용 프로그램이 앞에서 설명한 방법 중 하나를 사용하는 것으로 상상합니다. 그러나 모르겠습니다.

.mix파일 에 대한 혼합물 문서에서 :

믹스 파일은 .mix가 포함 된 .js 또는 .css 파일입니다. 파일 이름에. 혼합 파일은 일반 스타일 또는 스크립트 파일의 기능을 단순히 확장하여 가져오고 결합 할 수있게합니다.

다음 .mix은 여러 .js파일을 하나의 파일로 결합한 예제 파일입니다 .

// 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는이를 scripts-global.js축소 버전 ( scripts-global.min.js) 으로 출력합니다 .

참고 : 프런트 엔드 개발 도구로 사용하는 것 이외에는 어떤 방식 으로든 Mixture와 제휴 관계가 아닙니다. 나는 .mixMixture 상용구 중 하나에서 JavaScript 파일 을 보았을 때이 질문을 보았고 약간 혼란 스러웠다. ( "할 수 있니?"라고 생각했다.) 그런 다음 응용 프로그램 별 파일 유형 (다소 실망스럽고 동의 함)임을 깨달았습니다. 그럼에도 지식이 다른 사람들에게 도움이 될 수 있다고 생각했습니다.

업데이트 : 이제 혼합물이 무료입니다 (오프라인).

업데이트 : 혼합물은 이제 생산이 중단되었습니다. 이전 버전의 출시 는 계속 사용할 수 있습니다.


더 나은 jQuery 방식을 사용하십시오 . 준비 이벤트를 지연 시키려면 먼저 호출하십시오 $.holdReady(true). 예 ( source ) :

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

유용한 자바 스크립트 플러그인 모음을 유지하는 간단한 방법을 찾고 있었기 때문에이 질문에 답했습니다. 여기 몇 가지 해결책을 본 후에, 나는 이것을 생각해 냈습니다.

  1. "plugins.js"(또는 extensions.js 또는 무엇을 가지고 있는지)라는 파일을 설정하십시오. 그 하나의 마스터 파일과 함께 플러그인 파일을 유지하십시오.

  2. plugins.js에는 each ()를 반복 할 pluginNames [] "라는 배열이 있습니다. 그런 다음 각 플러그인의 헤드에 태그를 추가합니다.

    // 플러그인 파일을 추가하거나 제거 할 때 업데이트 할 배열을 설정합니다. var pluginNames = [ "lettering", "fittext", "butterjam"등]; // 플러그인마다 하나의 스크립트 태그 $ .each (pluginNames, function () {$ ( 'head'). append ( '');});

  3. 수동으로 머리에서 하나의 파일 만 호출하십시오.
    <script src="js/plugins/plugins.js"></script>

나는 모든 플러그인이 헤드 태그에 떨어지지 만 페이지를 클릭하거나 새로 고침 할 때 항상 브라우저에 의해 실행되는 것은 아니 었음을 발견했습니다.

PHP 태그에 스크립트 태그를 쓰는 것이 더 안정적이라는 것을 알았습니다. JavaScript를 사용하여 플러그인을 호출하는 것만 큼 많은 작업이 필요합니다.


이 질문에는 많은 잠재적 인 해답이 있습니다. 내 답변은 분명히 그 중 다수를 기반으로합니다. 이것은 내가 모든 대답을 읽은 후에 끝났습니다.

$.getScript로드가 완료 될 때 콜백을 필요로하는 문제와 실제로 다른 솔루션은 여러 파일을 사용하고 서로에 의존하는 경우 모든 스크립트가로드 된 시점을 더 이상 알지 못하는 경우 (일단 중첩되면 여러 파일에서).

예:

file3.js

var f3obj = "file3";

// Define other stuff

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

Ajax를 동 기적으로 실행하도록 지정하거나 XMLHttpRequest 사용할 수 있다고 말하면 현재 상황이 동기 요청을 비추천하는 것으로 보이므로 현재 또는 미래에 풀 브라우저 지원을받지 못할 수도 있습니다.

$.when지연된 객체의 배열을 검사 하려고 시도 할 수는 있지만 이제는 모든 파일에서이 작업을 수행 $.when하고 콜백이 실행되지 않으면 file2가로드되는 것으로 간주 되므로 file3이로드되기 전에 file1이 계속 실행됩니다 . 이것은 실제로 여전히 동일한 문제를 가지고 있습니다.

나는 포워드 대신에 뒤로 가기로 결정했다. 고마워 document.writeln. 나는 그것이 금기라는 것을 알고 있지만 올바르게 사용된다면 이것은 잘 작동합니다. 결국 쉽게 디버깅 할 수있는 코드로 끝나고 DOM에 올바르게 표시되며 종속성이 올바르게로드 된 순서를 확인할 수 있습니다.

물론 $ ( "body"). append ()를 사용할 수 있지만 더 이상 올바르게 디버깅 할 수 없습니다.

참고 : 페이지를로드하는 동안에 만 사용해야하며, 그렇지 않으면 빈 화면이 나타납니다. 즉, 항상 document.ready의 앞 / 뒤에 배치하십시오 . 페이지가 클릭 이벤트 또는 그와 비슷한 방식으로로드 된 후에 이것을 사용하여 테스트하지는 못했지만 실패 할 것이라고 확신합니다.

jQuery를 확장하는 아이디어가 마음에 들었지만 분명히 필요하지는 않습니다.

호출하기 전에 document.writeln모든 스크립트 요소를 평가하여 스크립트가 아직로드되지 않았는지 확인합니다.

스크립트가 document.ready이벤트가 실행될 때까지 완전히 실행되지 않는다고 가정합니다 . (나는 사용하는 document.ready것이 필수는 아니지만 많은 사람들이 그것을 사용한다는 것을 알고 있으며이를 처리하는 것은 보호 장치입니다.)

추가 파일이로드되면 document.ready콜백은 잘못된 순서로 실행됩니다. 스크립트가 실제로로드 될 때이를 처리하기 위해 스크립트를 가져온 스크립트가 다시 가져와 져서 실행이 중지됩니다. 이로 인해 원래 파일은 document.ready가져 오는 모든 스크립트에서 콜백이 실행 된 후 실행됩니다.

이 접근 방식 대신에 jQuery를 수정할 수는 readyList있지만, 이것은 더 나쁜 해결책처럼 보입니다.

해결책:

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

용법:

File3 :

var f3obj = "file3";

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

File2 :

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

File1 :

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

필자는 JavaScript로 모듈 스크립트를 임포트 / 자동화하는 작업을 자동화하는 간단한 모듈을 작성했습니다. 코드에 대한 자세한 설명은 JavaScript 게시물 require / import / include 모듈을 참조하십시오 .

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




include