1

EDIT : SORRY, PROBLEM IS DIFFERENT - It should be <textarea id="txtScene"> instead of <textarea name="txtScene">


It seems that <body onLoad="init();"> executes init(); before all HTML contend inside body is created.

I particular, have this HTML:

<script src="/home/prokop/Dropbox/MyDevSW/javascript/WebGL/shader_builder/GLSLscreen.js"></script>
<body onLoad="init_GLSLScreen();">
    <textarea name="txtScene" cols="60" rows="20" onChange="updateShader(this)">
        vec4 scene( Ray ray ){
            vec4 hit = vec4( POSITIVE_INF, vec3(0.0) );
            Sphere SURF1 = Sphere( vec3(0.0,0.0,0.0), 1.0 );
            Sphere SURF2 = Sphere( vec3(1.0,0.0,0.0), 0.75 );
            Sphere SURF3 = Sphere( vec3(0.0,1.0,0.0), 0.75 );
            vec2 ts1;
            ADD( SURF1 );
            SUB( SURF2 );
            SUB( SURF3 );
            return hit;
        } 
    </textarea>
</body>

and inside init_GLSLScreen() I need to run updateShader with textarea name="txtScene" as an argument. Like this

function init_GLSLScreen(){
    // ... some stuff ... don't care
    console.log ( document.getElementById("txtScene") );
    updateShader( document.getElementById("txtScene") );
    // ... some stuff ... don't care
}

But document.getElementById("txtScene") returns null

The problem is described here with solution to either move the javascript below HTML (I guess not possible in my case) or to run the javascript onLoad ... which I do but does not work.


Striped down code which reproduces this behaviour (if you look into web-console)

<!DOCTYPE html>
<html>
<head>
    <title>05.10 - Custom fragment shader</title>
    <style>
        body { margin: 0; overflow: hidden; }
    </style>
</head>
<script>
     function init_GLSLScreen(){
        console.log ( document.getElementById("txtScene") );
        console.log ( document.getElementById("txtScene").value );
    }
</script>
    <body>
        <textarea name="txtScene" cols="60" rows="20" onChange="updateShader(this)">
            sfsdjfskldjflj
        </textarea>
    </body>
    <script>
     init_GLSLScreen();
    </script>
</html>
Community
  • 1
  • 1
Prokop Hapala
  • 2,424
  • 2
  • 30
  • 59
  • 1
    Possible duplicate of [Execute Javascript When Page Has Fully Loaded](http://stackoverflow.com/questions/1033398/execute-javascript-when-page-has-fully-loaded) – Dez Apr 28 '17 at 17:46
  • I use `window.onload` but does work (still some elements are not initialized) – Prokop Hapala Apr 28 '17 at 17:48
  • 1
    Am I blind or is there no `id="txtScene"` in the textarea? You want to select an element by id, so you have to add it ` – Andréle Apr 28 '17 at 18:18
  • Andrele > Yes, I just realized that. I was thinking `name` is the same thing as `id` ... I have no experience with javascript – Prokop Hapala Apr 28 '17 at 18:25

2 Answers2

1

You could always move your function execution to the bottom of the html, just before the closing body tag. This will ensure that everything is loaded in the DOM.

<script>
   init_GLSLScreen();
</script>
0

If you can include jquery then it's a matter of wrapping your code in $(document).ready(function() {}); see: https://learn.jquery.com/using-jquery-core/document-ready/

if you can't /don't want to include jquery then I would get the javascript that makes up the source of the .ready function in jquery that way you can duplicate the same functionality.

See here for a plan: $(document).ready() source

If you wanted to use jquery you can just do this:

<script
  src="https://code.jquery.com/jquery-1.12.4.js"
  integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU="
  crossorigin="anonymous"></script>
<script src="/home/prokop/Dropbox/MyDevSW/javascript/WebGL/shader_builder/GLSLscreen.js"></script>
<script>
    $(document).ready(function() {
        init_GLSLScreen();
     });
</script>
<body >
    <textarea name="txtScene" cols="60" rows="20" onChange="updateShader(this)">
        vec4 scene( Ray ray ){
            vec4 hit = vec4( POSITIVE_INF, vec3(0.0) );
            Sphere SURF1 = Sphere( vec3(0.0,0.0,0.0), 1.0 );
            Sphere SURF2 = Sphere( vec3(1.0,0.0,0.0), 0.75 );
            Sphere SURF3 = Sphere( vec3(0.0,1.0,0.0), 0.75 );
            vec2 ts1;
            ADD( SURF1 );
            SUB( SURF2 );
            SUB( SURF3 );
            return hit;
        } 
    </textarea>
</body>
Community
  • 1
  • 1
Avitus
  • 15,640
  • 6
  • 43
  • 53
  • Hi, thanks ... I don't know what `jquery` is. I'm not web programer ... I just use javascript as a simple way how to present my GLSL shaders on github. – Prokop Hapala Apr 28 '17 at 17:45
  • I tried, but still I get `null` ... perhaps there is different problem ... but I don't see what. I use `three.js` if that matters somehow – Prokop Hapala Apr 28 '17 at 17:58