Javascript 从包含的JS文件访问全局变量

Javascript 从包含的JS文件访问全局变量,javascript,global-variables,Javascript,Global Variables,我想从包含的JS文件中访问全局变量。是的,我看到了,我不是第一个遇到这个问题的人,但是这里的答案对我来说并不适用。我在代码中写了一些注释,这些注释描述了我的问题 main.js var drawing_area; var renderer; var camera; var tableTop; var scene; var OBJECT3D = {}; // the global namespace var texture_path = "/images/materials/texture_1

我想从包含的JS文件中访问全局变量。是的,我看到了,我不是第一个遇到这个问题的人,但是这里的答案对我来说并不适用。我在代码中写了一些注释,这些注释描述了我的问题

main.js

var drawing_area;
var renderer;
var camera;
var tableTop;
var scene;

var OBJECT3D = {}; // the global namespace

var texture_path = "/images/materials/texture_1.jpg";
var texture;


$(function() {

    // get the product-identifier via URL
    OBJECT3D.productIdentifier = document.URL.split('/').pop();


    // get all default values from select-elements and store them in a global hash
    OBJECT3D.defaultValues = {};
    $('select').each(function() {
        var selectedOption = $(this).find('option:selected');
        OBJECT3D.defaultValues[$(this).data('identifier')] = selectedOption.text();
    });


    /*
     *  ####################################################
        *  SET ALL DEFAULT VALUES DEPENDING ON THE PRODUCT *
     *  ####################################################
     *  
     *  import custom js-code via <script> - Tag   
     *
     */
    var script_values_setter   = document.createElement("script");
    script_values_setter.type  = "text/javascript";


    switch (OBJECT3D.productIdentifier) {

        case "product_01":
            script_values_setter.src   = "/javascripts/3D_models/default_values_setters/product_01.js"; // include js-File
            document.body.appendChild(script_values_setter); // append it to the DOM

            break;
        // ...
        default:
            break;
    }

// try to access the length, which i set in product_01.js, but it's undefined, so i can't use it
console.log("length-value: "+OBJECT3D.lengthProduct01);

// ... some other stuff for what i need the values of the product_01.js - File



});
所以问题是,在product_01.js-文件中设置值后,我无法访问OBJECT3D.lengthProduct01。求你了,我需要帮助!这已经花了我很多时间了!:(


谢谢!

JavaScript是单线程环境。当您执行
document.body.appendChild(script\u values\u setter)时,
脚本将添加到DOM中,但直到当前脚本结束后才进行处理。 然后,当您的程序到达带有
OBJECT3D.lengthProduct01
的行时,该值未设置。您必须先结束脚本,让另一个脚本有一些时间,然后才能访问
OBJECT3D.lengthProduct01
属性。您应该尝试以下操作:

// invoke function later (in 1ms)
// During the wait phase JS engine will grant a processor time to another scripts (timer functions, callbacks for events, etc.)
window.setTimeout(function() {
    // try to access the length, which i set in product_01.js - this should works
    console.log("length-value: "+OBJECT3D.lengthProduct01);

    // ... some other stuff for what i need the values of the product_01.js - File
}, 1);
此示例无法正常工作,因为等待限制太小,正确的值(不太小也不太高)取决于连接。您可以使用10000ms或类似的方法测试is,它几乎总是可以工作的,但它太长了

更好的解决方案是使用jQuery函数而不是setTimeout

    ...
    switch (OBJECT3D.productIdentifier) {
        case "product_01":
            // append js-File to the DOM
            $.getScript("/javascripts/3D_models/default_values_setters/product_01.js", function() {
                // try to access the length, which i set in product_01.js - this should works
                console.log("length-value: "+OBJECT3D.lengthProduct01);

                // ... some other stuff for what i need the values of the product_01.js - File
            });
            break;
        // ...
        default:
            break;
    }
    // nothing here - the code is moved to getScript callback function
});

这是我的工作示例

,这是我的解决方案,对我来说很有用:

/*
     *  ####################################################
        *  SET ALL DEFAULT VALUES DEPENDING ON THE PRODUCT *
     *  ####################################################
     *
     */

    function setJsScript(path, callback) {
        var script                = document.createElement('script');
        script.type               = 'text/javascript';
        script.src                = path;
        script.onreadystatechange = callback;
        script.onload             = callback;
        document.getElementsByTagName('body')[0].appendChild(script);
    }


    switch (OBJECT3D.productIdentifier) {
        case "product_01":

            setJsScript('/javascripts/3D_models/default_values_setters/product_01.js', function(){
                console.log("-> length-value: "+OBJECT3D.lengthTableTop); // now i cann access the var :)
                // some other stuff ...
            });

            break;
        default:
            break;
    }

希望这能帮助其他有同样问题的人!;-)

您尝试过通过窗口访问全局视图吗?是的,Manuel Richarz。但它不起作用……谢谢@BorisŠuška的回答。我也有同样的想法,并再次尝试,但这不起作用:(我现在有了一个新的想法:我编写了一个带有onreadystatechange和回调的函数。如果它有效,我将在这里发布。欢迎使用任何其他解决方案!您是否尝试将超时设置为更高的值?出于测试目的,设置为5000ms?user1542555提醒我,加载和解析js文件需要一段时间。如果更高的超时值有效,那么您就必须这样做。)等待js文件加载。
onreadystatechange
用于AJAX调用,而不是用于脚本加载(向DOM添加脚本不是AJAX)。比混合使用原生JS代码和jQuery更好。我建议您使用
$.ajax
回调函数或
$.getScript
回调函数。我将更新我的答案。是的,我也尝试了更高的值。但这不起作用。真的很奇怪……是的,您是对的,Boris,这不是最好的解决方案,但对我来说,它是有效的。我已经尝试了也使用了$.getScript,但使用此函数时,我遇到了一个问题,即无法访问变量。我添加了一个指向工作示例的链接。请查看。这两种解决方案都有。
/*
     *  ####################################################
        *  SET ALL DEFAULT VALUES DEPENDING ON THE PRODUCT *
     *  ####################################################
     *
     */

    function setJsScript(path, callback) {
        var script                = document.createElement('script');
        script.type               = 'text/javascript';
        script.src                = path;
        script.onreadystatechange = callback;
        script.onload             = callback;
        document.getElementsByTagName('body')[0].appendChild(script);
    }


    switch (OBJECT3D.productIdentifier) {
        case "product_01":

            setJsScript('/javascripts/3D_models/default_values_setters/product_01.js', function(){
                console.log("-> length-value: "+OBJECT3D.lengthTableTop); // now i cann access the var :)
                // some other stuff ...
            });

            break;
        default:
            break;
    }