简体   繁体   中英

Accessing global Variables from included JS-File

i want to access global variables from an included JS-File. Yes, i saw, that i'm not the first one with this problem here, but nothing from the answers here works for me. I wrote some comments in my code, which describe my problem.

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

// in here i can access the global variable OBJECT3D.defaultValues without any problems ...
$.each(OBJECT3D.defaultValues, function(key, value) {
        switch (key) {
            case "laenge":
                // here i set the length in a global var
                OBJECT3D.lengthProduct01 = value.replace(/[A-Za-z$-]/g, "")*10; 
                break;
            case "breite":
                OBJECT3D.widthProduct01 = value.replace(/[A-Za-z$-]/g, "")*10;
                break;
            default:
                break;
        }
    });

So the problem is that i can't access OBJECT3D.lengthProduct01 after setting the value in the product_01.js - File. Please, i need some help! This costs me a lot of time already! :(

Thanks!

JavaScript is single thread environment. When you do document.body.appendChild(script_values_setter); script is added to the DOM, but not processed until current script ends. Then, when your program reach line with OBJECT3D.lengthProduct01 the value is not set. You have to end your script first let some time for another script and then you can access OBJECT3D.lengthProduct01 property. You should try something like this:

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

This example doesn't work properly because waiting limit is too small and proper value (not too small and not too high) depends on connection. You can test is with 10000ms or something like this, it will work almost always, but it is too long.

Better solution is use jQuery function getScript instead of 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
});

Here is my working example http://ulozto.net/xSprWGU8/load-script-zip

so here is my solution, which works for me:

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

hope this helps others with the same problem! ;-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM